阿华代码,不是逆风,就是我疯
你们的点赞收藏是我前进最大的动力!!
希望本文内容能够帮助到你!!
目录
文章导读
零:项目结果展示
一:后端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;}