【从0做项目】Java搜索引擎(7) web模块

阿华代码,不是逆风,就是我疯

你们的点赞收藏是我前进最大的动力!!

希望本文内容能够帮助到你!!

目录

文章导读

零:项目结果展示

一:后端web模块

1:思路

2:设计

3:注意点

(1)设置响应头格式

(2)方法返回类型

(3)实例化DocSearch

二:前端代码

 1:head标签

 2:body标签

(1)div标签

(2)style标签

(3)script标签

三:前端显示优化&后端联动

1:实现前端搜索关键字标红

(1)实现逻辑

(2)正则表达式

2:后端代码

3:呈现效果


文章导读

阿华将发布项目复盘系列的文章,旨在:

1:手把手细致带大家从0到1做一个完整的项目,保证每2~3行代码都有详细的注解

2:通过文字+画图的方式,对项目进行整个复盘,更好的理解以及优化项目

3:总结自己的优缺点,扎实java相关技术栈,增强文档编写能力

零:项目结果展示

项目目前已经上线,小伙伴们可以进行使用!!!

Java 文档搜索

简述:在我的搜索引擎网站,用户进行关键字搜索,就可以查询到与这个关键字相关的java在线文档,(包含标题,关键字附近的简述,url),用户点击标题,即可跳转到相关在线文档,适用于JDK17版本。

一:后端web模块

1:思路

提供一个web接口,最终以网页的形式,把我们的程序呈现给用户~~

前端(HTML+CSS+JS)+ 后端(Java,Script、Spring)

约定前后端通信接口,

需要明确的描述出,服务器能够接收什么样的请求,返回什么样的响应~~

2:设计

这里我们只需要实现一个搜索接口即可~~!!

3:注意点

(1)设置响应头格式

这里我们还是使用Jackson库(Jackson我滴神)中ObjectMapper类来实现json和Java对象之间的转换~~,在返回的ContentType中我们需要设置一下 produces= “application/json;charset=utf-8”

(2)方法返回类型

这里我们把多个Result封装为集合的形式进行返回

(3)实例化DocSearch

我们用到DocSearch类中的search方法所以需要对类进行实例化

@RestController
@RequestMapping("/docSearch")
@Slf4j
public class DocSearcherController{private static DocSearcher docSearcher = new DocSearcher();//这里实例化对象后,直接就把构造好的索引加载到内存当中了。(DocSearcher中的构造方法)private ObjectMapper objectMapper = new ObjectMapper();@RequestMapping(value = "/searcher" , produces = "application/json;charset=utf-8")@ResponseBodypublic String search(@RequestParam("query") String query) throws JsonProcessingException {log.info("后端接收到参数query:{}",query);List<Result> results = docSearcher.search(query);return objectMapper.writeValueAsString(results);}
}

二:前端代码

注:博主是后端选手,前端代码这里学的比较浅,通过多方面的帮助,以及阿华的修改查验,完成了前端页面的个性化简单制作,这里我只对我们js代码中的ajax请求进行讲解,大家可以根据自己的审美进行前端页面的制作!!

js源代码不会整的可以在阿华博文中搜索jquery,手把手教你

 1:head标签

<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Java 文档搜索</title>
</head>

 2:body标签

(1)div标签

<!-- 通过 .container 来表示整个页面的元素容器 --><div class="container"><!-- 搜索框+搜索按钮 --><div class="header"><input type="text"><button id="search-btn">搜索</button></div><!-- 显示搜索结果 --><div class="result"><!-- 每一条item表示一个结果 --><!-- <div class="item"><a href="#">我是标题</a><div class="desc">我是一段描述嘿嘿嘿,落魄谷中寒风吹,春秋蝉鸣少年归,荡魂山处石人泪,定仙游走魔向北</div><div class="url">https://blog.csdn.net/qq_42257666/article/details/105701914</div></div><div class="item"><a href="#">我是标题</a><div class="desc">我是一段描述嘿嘿嘿,落魄谷中寒风吹,春秋蝉鸣少年归,荡魂山处石人泪,定仙游走魔向北</div><div class="url">https://blog.csdn.net/qq_42257666/article/details/105701914</div></div> --></div></div>

(2)style标签

<style>/*去除浏览器默认样式*/* {margin: 0;padding: 0;box-sizing: border-box;}/* 指定页面高度 */html,body {height: 100%;background-image: url(image/light.jpg);/* 不平铺 */background-repeat: no-repeat;/* 设置背景图位置 */background-position: center center;/* 背景图大小 */background-size: cover;}/* 对内容实现版心效果 */.container {width: 1200px;height: 100%;/* 水平居中 */margin: 0 auto;/* 背景色和透明度 */background-color: rgba(255, 255, 255, 0.6);/* 圆角 */border-radius: 10px;/* 内边距 */padding: 20px;/* 页面滚动 */overflow: auto;}/* 对内容样式进行设置 */.header{width: 100%;height: 50px;/* 框+按钮弹性设置 */display: flex;justify-content: space-between;align-items: center;}.header>input{width: 1050px;height:50px;/* 输入框中字体大小,高度,左边距 */font-size: 22px;line-height: 50px;padding-left: 10px;border-radius: 10px;}.header>button{width: 100px;height: 50px;/* 按钮颜色、字体大小、高度 */background-color:rgb(42, 107, 205) ;color: antiquewhite;font-size: 22px;line-height: 50px;/* 圆角 */border-radius: 10px;border: none;}.header>button:active{background-color: gray;}/* 给搜索结果数字统计css一下 */.result .count{color: gray;margin-top: 10px;}.item{width: 100%;/* 元素顶部外边距,把每一条item间隔开来 */margin-top: 20px;}.item a{/* 块级元素 */display: inline;height: 40px;/* 字体大小高度粗度 */font-size: 20px;line-height: 40px;font-weight: 700;color:rgb(42, 107, 205);}.item .desc{font-size: 18px;}.item .url{font-size: 18px;color: rgb(0,128,0);}/* 把后端设置的i标签中的内容加红 */.item .desc i {color: red; /* 去斜体 */font-style: normal;}</style>

(3)script标签

<script src="js/jquery.js"></script>

思路:

第一步:前端返回的list集合中有好多个Result对象

第二步:我们遍历,对每一个Result进行处理

这里逻辑比较简单,大家边看代码边看注释会比较好理解一点!

<script>// js核心代码let button = document.querySelector("#search-btn");button.onclick = function(){//获取输入框的内容let input = document.querySelector(".header input");let query = input.value;console.log("query:" + query);$.ajax({type: "GET",url: "docSearch/searcher?query=" + query,success: function(data , status){buildResult(data);}});}function buildResult(data){// 把data中每一个元素,把每一个元素都构建成一个div.item,再加入到div.result中let result = document.querySelector('.result');//每次搜索把前一次的结果清空result.innerHTML = '';//显示搜索的结果个数let countDiv = document.createElement('div');countDiv.innerHTML = '当前找到' + data.length + '个结果';countDiv.classNamee = 'count';result.appendChild(countDiv);for(var item of data){let itemDiv = document.createElement('div');itemDiv.className = 'item';//构造一个标题let title = document.createElement('a');title.href = item.url;title.innerHTML = item.title;title.target = '_blank';itemDiv.appendChild(title);//构造描述let desc = document.createElement('div');desc.className = 'desc';desc.innerHTML = item.desc;itemDiv.appendChild(desc);//构造urllet url = document.createElement('div');url.className = 'url';url.innerHTML = item.url;itemDiv.appendChild(url);result.appendChild(itemDiv);}}</script>

三:前端显示优化&后端联动

1:实现前端搜索关键字标红

【从0做项目】Java搜索引擎(5)-CSDN博客

这篇文章介绍了正文的一个处理逻辑

(1)实现逻辑

①我们修改后端代码,生成搜索结果的时候,把其中包含查询词的部分,加上一个标记,例如:给这部分加<i>标签,这样前端就可以进行处理了

②前端针对这个<i>标签设置样式,我是给标红了!!(写的时候华也红温了)


(2)正则表达式

依然是掏出我们的正则表达式

2:后端代码

第一步:对正文进行处理,转小写,把标点和空格全部替换成空格,这样单词与单词之间就以空格分隔开来

第二步:遍历搜索词句的分词,在正文中锁定位置(只要找到一个就break)

第三步:截取一定长度正文,这里不做过多描述,之前有详细介绍

第四步:在正文中把所有term关键字给替换成

举个例子:

单词1 空格 word 空格 单词2 空格 ——》     

"空格"+word+"空格"     ——>     <i>word<i/>

"(?i)"这是一个正则表达式的修饰符,表示忽略大小写,可以理解成,在匹配过程中,不区分字母的大小写。

    private String GenDesc(String content , List<Term> terms){//遍历分词结果,看哪个int firstPos = -1;for(Term term : terms){String word = term.getName();
//            firstPos = content.toLowerCase().indexOf(" " + word + " ");//避免包含关系 例:查array  结果查到ArrayList//使用正则表达式,indexOf不支持正则,我们曲线救国!!content = content.toLowerCase().replaceAll("\\b" + word + "\\b" , " " + word + " ");//匹配标点符号和空格,全部替换成空格firstPos = content.indexOf(" " + word + " ");//女少if(firstPos >= 0){break;//找到了位置,可能这个content中会包含多个term,我们只取第一个}}//用户输入的词,在正文中没有出现,虽然有点扯,但还是处理一下这种情况if(firstPos == -1){if(content.length() > 160){return content.substring(0,160) + "...";}return content;//我去测试了一下,还真有这种情况离谱!说明查的词在标题中出现了,但是正文没出现666,这里也要对正文的长度做一下判断}//截取一部分正文String desc = "";int descBeg = firstPos < 60 ? 0 : firstPos - 60;if(descBeg + 160 > content.length()){desc = content.substring(descBeg);}else {desc = content.substring(descBeg , descBeg + 160) + "...";}for(Term term : terms){String word = term.getName();desc = desc.replaceAll("(?i) " + word + " " , "<i> " + word + "</i> ");//正则忽略大小写全字段匹配,那头单词和尾单词呢?}return desc;}

3:呈现效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/21628.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掌握.NET Core后端发布流程,如何部署后端应用?

无论你是刚接触.NET Core的新手还是已有经验的开发者&#xff0c;在这篇文章中你将会学习到一系列实用的发布技巧与最佳实践&#xff0c;帮助你高效顺利地将.NET Core后端应用部署到生产环境中 目录 程序发布操作 Docker容器注册表 文件夹发布 导入配置文件 网站运行操作 …

嵌入式工业级显示器在环保垃圾柜设备中发挥着至关重要的作用

嵌入式工业级显示器在环保垃圾柜设备中发挥着至关重要的作用。以下是其具体作用的分析&#xff1a; 一、提供交互界面 嵌入式工业级显示器为环保垃圾柜设备提供了一个直观、易用的交互界面。用户可以通过触摸屏幕进行操作&#xff0c;如选择垃圾分类类别、查看投放指南、查询…

Apifox 增强 AI 接口调试功能:自动合并 SSE 响应、展示DeepSeek思考过程

在API调试的世界里&#xff0c;效率和准确性往往决定了开发者的成败。你是否曾为处理SSE&#xff08;Server-Sent Events&#xff09;响应而烦恼&#xff1f;又是否期待在调试时能直观看到AI的“思考过程”&#xff1f;Apifox这次全新升级&#xff0c;将AI接口调试功能推向新高…

[python]windows上安装yolov12环境

yolov12出来了&#xff0c;地址github.com/sunsmarterjie/yolov12&#xff0c;咱们看看怎么在windows上把环境安装一下首先看看官方安装流程&#xff1a; wget https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.3/flash_attn-2.7.3cu11torch2.2cxx11abiF…

前端知识点---vue的声明周期(vue)

文章目录 创建挂载更新销毁 vue的生命周期有四个阶段: 创建 挂载, 更新和销毁 创建 是vue组件从创建到准备渲染的过程 dom还没挂载到页面中 进行了初始化工作: 初始化数据(data,props) . 设置计算属性computed 初始化方法 methods 绑定事件watch 创建阶段的钩子函数beforeCrea…

装修流程图: 装修前准备 → 设计阶段 → 施工阶段 → 安装阶段 → 收尾阶段 → 入住

文章目录 引言I 毛坯房装修的全流程**1. 装修前准备****1.1 确定装修预算****1.2 选择装修方式****1.3 选择装修公司****1.4 办理装修手续****2. 设计阶段****2.1 量房****2.2 设计方案****2.3 确认方案****3. 施工阶段****3.1 主体拆改****3.2 水电改造****3.3 防水工程****3.…

智能马达保护器:为工业电机安全运行保驾护航

在工业生产中&#xff0c;电动机作为核心动力设备&#xff0c;其稳定运行直接关系到生产效率与安全性。然而&#xff0c;复杂的工况环境、频繁启停和突发负载变化&#xff0c;常导致电机面临过载、缺相、短路等故障风险。安科瑞智能马达保护器凭借其智能化、高精度、多功能的设…

Unity学习part4

1、ui界面的基础使用 ui可以在2d和矩形工具界面下操作&#xff0c;更方便&#xff0c;画布与游戏窗口的比例一般默认相同 如图所示&#xff0c;图片在画布上显示的位置和在游戏窗口上显示的位置是相同的 渲染模式&#xff1a;屏幕空间--覆盖&#xff0c;指画布覆盖在游戏物体渲…

雷龙CS SD NAND(贴片式TF卡)测评体验

声明&#xff1a;非广告&#xff0c;为用户体验文章 前段时间偶然获得了雷龙出品的贴片式 TF 卡芯片及转接板&#xff0c;到手的是两片贴片式 nand 芯片搭配一个转接板&#xff0c;其中有一片官方已经焊接好了&#xff0c;从外观来看&#xff0c;正面和背面设计布局合理&#x…

tailwindcss学习01

系列教程 01 入门 02 vue中接入 03 工具类优先 入门 # 注意使用cmd不要powershell npm init -y # 如果没有npx则安装 npm install -g npx npm install -D tailwindcss3.4.17 --registry http://registry.npm.taobao.org npx tailwindcss init修改tailwind.config.js /** ty…

爱普生SG-8002CE智能家居中控系统的精准 “心脏起搏器”

智能家居中控系统是整个智能家居生态的关键枢纽&#xff0c;承担着连接、管理和协调各类智能设备的重任&#xff0c;涵盖智能灯光、智能窗帘、智能家电等&#xff0c;致力于实现家居设备的互联互通与智能化控制&#xff0c;打造便捷、舒适的智慧生活环境。在这一系统中&#xf…

python绘制年平均海表温度、盐度、ph分布图

python绘制年平均海表温度、盐度、ph图 文章目录 python绘制年平均海表温度、盐度、ph分布图前言一、数据准备二、代码编写2.1. python绘制年平均海表温度&#xff08;主要&#xff09;2.2. python绘制年平均海表盐度&#xff08;选看&#xff09;2.3. python绘制年平均海表ph&…

基于海思soc的智能产品开发(图像处理的几种需求)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于一个嵌入式设备来说&#xff0c;如果上面有一个camera&#xff0c;那么就可以有很多的用途。简单的用途就是拍照&#xff0c;比拍照更多一点的…

使用linux脚本部署discuz博客(详细注释版)

使用脚本部署一个discuzz项目 1.显示当前环境状态 防火墙状态 selinux状态 httpd状态 由上可知&#xff0c;虚拟机已处于最初始状态 2.脚本编写 #!/bin/bash #这是一个通过脚本来部署discuzz博客 firewalld关闭 systemctl stop firewalld if [ $? -eq 0 ];then echo "…

Windows 快速搭建C++开发环境,安装C++、CMake、QT、Visual Studio、Setup Factory

安装C 简介 Windows 版的 GCC 有三个选择&#xff1a; CygwinMinGWmingw-w64 Cygwin、MinGW 和 mingw-w64 都是在 Windows 操作系统上运行的工具集&#xff0c;用于在 Windows 环境下进行开发和编译。 Cygwin 是一个在 Windows 上运行的开源项目&#xff0c;旨在提供类Uni…

React创建项目实用教程

✍请将整篇文章阅读完再开始使用create-react-app react-project创建项目 检查node版本 node -v // node版本&#xff1a;v22.10.0使用nvm降版本修改到了node V20.11.1之后再进行一系列操作的 react脚手架安装&#xff1a; npm install -g create-react-app// node版本&…

RK3588配置成为路由器

文章目录 前言一、配置netplan二、安装hostapd1.创建hostapd.conf文件2.安装软件3.修改启动文件4.修改/etc/default/hostapd 文件 三、安装dnsmasq服务四、配置NET及重启验证五、常见问题总结 前言 RK3588开发板有两个网口&#xff0c;一个无线网卡。我需要配置为家用路由器模…

游戏引擎学习第114天

打开内容并回顾 目前正在讨论一个非常重要的话题——优化。当代码运行太慢&#xff0c;无法达到所需性能时&#xff0c;我们该怎么办。昨天&#xff0c;我们通过在代码中添加性能计数器&#xff0c;验证了一些性能分析的数据&#xff0c;这些计数器帮助我们了解每个操作需要的…

如何修改Windows系统Ollama模型存储位置

默认情况下&#xff0c;Ollama 模型会存储在 C 盘用户目录下的 .ollama/models 文件夹中&#xff0c;这会占用大量 C 盘空间&#xff0c;增加C盘“爆红”的几率。所以&#xff0c;我们就需要修改Ollama的模型存储位置 Ollama提供了一个环境变量参数可以修改Ollama的默认存在位…

第1章大型互联网公司的基础架构——1.2 客户端连接机房的技术1:DNS

客户端启动时要做的第一件事情就是通过互联网与机房建立连接&#xff0c;然后用户才可以在客户端与后台服务器进行网络通信。目前在计算机网络中应用较为广泛的网络通信协议是TCP/IP&#xff0c;它的通信基础是IP地址&#xff0c;因为IP地址有如下两个主要功能。 标识设备&…