阿華代碼,不是逆風,就是我瘋
你們的點贊收藏是我前進最大的動力!!
希望本文內容能夠幫助到你!!
目錄
文章導讀
零:項目結果展示
一:后端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;}