一. 整合websocket
1.1長連接和短連接
1.2 springboot整合websocket
第一步:導入包
第二步:編寫配置類
第三步:編寫簡單代碼:
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-websocket/<artifactid>
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
@ServerEndpoint(value = "/websocket")
@Component
public class MyWebSocket {
//當前連接數(注意:此處是非線程安全的)
private static int count = 0;
//使用線程安全的方式存放每個客戶端對應的MyWebSocket對象
private static CopyOnWriteArraySet<mywebsocket> webSocketSet = new/<mywebsocket>
CopyOnWriteArraySet<mywebsocket>();/<mywebsocket>
//與客戶端的連接會話
private Session session;
/**
* 連接建立成功調用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在線數加1
try {
sendMessage("當前在線人數為" + getOnlineCount());
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO異常");
}
}
/**
* 連接關閉調用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //從set中刪除
subOnlineCount(); //在線數減1
System.out.println("有一連接關閉!當前在線人數為" + getOnlineCount());
}
/**
* 收到客戶端消息後調用的方法
* @param message 客戶端發送過來的消息*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("來自客戶端的消息:" + message);
//群發消息
for (MyWebSocket item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 發生錯誤時調用
@OnError
*/
public void onError(Session session, Throwable error) {
System.out.println("發生錯誤");
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return count;
}
public static synchronized void addOnlineCount() {
count++;
}
public static synchronized void subOnlineCount() {
count--;
}
html頁面: index.ftl
}
<title>簡單聊天室/<title>
value="發送"/>
var websocket = null;
//判斷當前瀏覽器是否支持WebSocket
if('WebSocket' in window){
websocket = new WebSocket("ws://localhost:8080/websocket");
}
else{
alert('當前瀏覽器不支持websocket')
}
//連接錯誤回調
websocket.onerror = function(){
showMessage("連接錯誤");
};
//連接成功回調
websocket.onopen = function(event){
showMessage("歡迎進入聊天室");
}
//接收消息回調
websocket.onmessage = function(event){
showMessage(event.data);
}
//連接關閉的回調方法
websocket.onclose = function(){
showMessage("連接關閉");
}
//監聽窗口關閉事件
// 窗口關閉時,需要關閉websocket連接
window.onbeforeunload = function(){
websocket.close();
}
//將消息顯示在網頁上
function showMessage(msg){
啟動類:
二. 整合solr
2.1 回顧solr
Solr 是Apache下的一個頂級開源項目,採用Java開發,它是基於Lucene的全文搜索服務器。Solr提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴展,並對索引、搜索性能進行了優化。
Solr可以獨立運行,運行在Jetty、Tomcat等這些Servlet容器中,Solr 索引的實現方法很簡單,用 POST 方法向 Solr 服務器發送一個描述 Field 及其內容的 XML 文檔,Solr根據xml文檔添加、刪除、更新索引 。Solr 搜索只需要發送 HTTP GET 請求,然後對 Solr 返回Xml、json等格式的查詢結果進行解析,組織頁面佈局。Solr不提供構建UI的功能,Solr提供了一個管理界面,通過管理界面可以查詢Solr的配置和運行情況。
Solr與Lucene的區別:
Lucene是一個開放源代碼的全文檢索引擎工具包,它不是一個完整的全文檢索引擎,Lucene提供了完整的查詢引擎和索引引擎,目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者以Lucene為基礎構建全文檢索引擎。
Solr的目標是打造一款企業級的搜索引擎系統,它是一個搜索引擎服務,可以獨立運行,通過Solr可以非常快速的構建企業的搜索引擎,通過Solr也可以高效的完成站內搜索功能。
2.2 solr的安裝和配置到tomcat中
document.getElementById('messageDiv').innerHTML += msg + '
';
}
//關閉連接
function closeWebSocket(){
websocket.close();
}
//發送消息
function send(){
var msg = document.getElementById('contentTxt').value;
websocket.send(msg);
}
@Controller
@SpringBootApplication
public class DemoApplication {
@RequestMapping("/")
public String index(){
return "/index";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2.3 安裝中文分詞器
使用IKAnalyzer中文分析器。
解壓分詞器壓縮包
第一步:把ik-analyzer-solr5-5.x.jar添加到tomcat中的solr/WEB-INF/lib目錄下。
第二步:複製IKAnalyzer的配置文件IKAnalyzer.cfg.xml和自定義詞典ext.dic和停用詞詞典stopword.dic到tomcat中的solr/WEB-INF/classpath下。
第三步:在solrhome/collection1/conf/managed-schema.xml中添加一個自定義的fieldType,使用中文分析器。
第四步:定義field,指定field的type屬性為text_ik
第五步:重啟tomcat
步驟:
1. 解壓縮後將solr5.5.5/server/solr-webapp中的webapp文件夾複製到tomcat的webapps目錄下,
並改名為solr
2. 將solr5.5.5/server/lib/ext中的所有jar包複製到tomcat下的solr/WEB-INF/lib下;
在solr的工程的WEB-INF下創建classes目錄,然後將
solr5.5.5\\server\\resources\\log4j.properties也複製到剛剛創建的classes目錄下;把solr-
5.5.5\\dist的solr-dataimporthandler-5.5.5.jar和solr-dataimporthandler-extras-
5.5.5.jar也放到solr的\\WEB-INF\\lib
3. 將solr5.5.5/server中的solr文件夾複製到隨便一個地方並改名為solrhome(此處我使用homework
目錄)
4. 將solrhome中的configsets中的sample_techproducts_configs複製出來與solr.xml平級,並
刪除掉configsets文件夾,將sample_techproducts_configs改名為collection1(此處
collection1為任意名稱)
5. 在solrhome/conf中創建一個文件core.properties,在裡面添加內容: name=collection1(此
處的collection1為上一步命名的名稱)
6. 將tomcat中的solr文件夾中的web.xml打開,找到被註釋掉的代碼:
將其註釋去掉,並將路徑改成自己的solrhome路徑。
<fieldtype>
<analyzer>
<field>
<field>
multiValued="true"/>
2.4 設置業務字段
如果不使用Solr提供的Field可以針對具體的業務需要自定義一套Field,如下是商品信息Field:,此處可以使用自己的配置,這裡僅做演示用
2.5 文檔基本操作
2.5.1 添加單個文檔
2.5.2 批量導入數據
使用dataimport插件批量導入數據。
第一步:把dataimport插件依賴的jar(dist 目錄下)包添加到solrhome(collection1\\lib)中,或者是 solr 的 web 項目 lib 中,並且複製數據庫連接依賴包(前面已經添加過了)
第二步:將mysql的驅動包放入到solr 的 web 項目 lib 中
第三步:配置solrconfig.xml文件,添加一個requestHandler。
第四步:創建一個data-config.xml,保存到collection1\\conf\\目錄下
<field>
<field>
<field>
stored="false" />
<field>
stored="false" multiValued="true"/>
<copyfield>
<copyfield>
<requesthandler>
class="org.apache.solr.handler.dataimport.DataImportHandler">
/<requesthandler>
<dataconfig> /<dataconfig>
<datasource>
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/solr"
user="root"
第四步:重啟tomcat
第五步:點擊"execute"按鈕導入數據 到入數據前會先清空索引庫,然後再導入。
2.5.3. 刪除文檔(注意需要提交)
刪除索引格式如下:
1) 刪除制定ID的索引
2) 刪除查詢到的索引數據
3) 刪除所有索引數據
password="root"/>
<document> /<document>
<entity>
<field>
<field>
<field>
<field>
<delete>
<delete>
<query>product_catalog_name:幽默雜貨/<query>
2.5.4. 查詢索引
通過/select搜索索引,Solr制定一些參數完成不同需求的搜索:
2.5.4.1 q
查詢字符串,必須的,如果查詢所有使用:
2.5.4.2 fq
(filter query)過慮查詢,作用:在q查詢符合結果中同時是fq查詢符合的,例如:
過濾查詢價格從1到20的記錄。
也可以在"q"查詢條件中使用product_price:[1 TO 20],如下:
也可以使用"*"表示無限,例如:
20以上:product_price:[20 TO *]
20以下:product_price:[* TO 20]
2.5.4.3. sort
排序,格式:sort=+<desc>[,+<desc>]… 。示例:/<desc>/<desc>
按價格降序
2.5.4.4. start
分頁顯示使用,開始記錄下標,從0開始
2.5.4.5. rows
指定返回結果最多有多少條記錄,配合start來實現分頁。
顯示前10條。
<delete>
<query>*:*/<query>
2.5.4.6. fl
指定返回那些字段內容,用逗號或空格分隔多個。
顯示商品圖片、商品名稱、商品價格
2.5.4.7. df
-指定一個搜索Field
也可以在SolrCore目錄 中conf/solrconfig.xml文件中指定默認搜索Field,指定後就可以直接在"q"查詢條件中輸入關鍵字。
2.5.4.8. wt
(writer type)指定輸出格式,可以有 xml, json, php, phps, 後面 solr 1.3增加的,要用通知我們,因為默認沒有打開。
2.5.4.9. hl
-是否高亮 ,設置高亮Field,設置格式前綴和後綴。(注意,必須有查詢條件才能高亮,即q中必須有條件,不能是* : *)
2.6 在springboot中操作solr
第一步:導入對應的包 pom.xml
第二步:添加配置 application.properties
第三步:編寫相應的代碼
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-data-solr/<artifactid>
spring.data.solr.host=http://127.0.0.1:8080/solr/collection1
@Repository
public class ProductSolrDAO {
@Resource
private SolrClient client;
/**
* 新增/修改 索引
* 當 id 存在的時候, 此方法是修改, 則是新增
* @return
*/
@RequestMapping("add")
public String add() {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
try {
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id", uuid);
doc.setField("product_name", "Oppo手機");
doc.setField("product_price", "3000");
// collection1為solrcore名稱,可以直接設置在url中
client.add(doc);
// client.add("collection1", doc);
client.commit();
// client.commit("collection1");
return uuid;
} catch (Exception e) {
e.printStackTrace();
}
return "error";
}
/**
* 根據id刪除索引
* @param id
* @return
*/
@RequestMapping("delete")
public String delete(String id) {
try {
client.deleteById("collection1",id);
client.commit("collection1");
return id;
} catch (Exception e) {
e.printStackTrace();
}
return "error";
}
/**
* 刪除所有的索引
* @return
*/
@RequestMapping("deleteAll")
public String deleteAll(){
try {
client.deleteByQuery("collection1","*:*");
client.commit("collection1");
return "success";
} catch (Exception e) {
e.printStackTrace();
}
return "error";
}
/**
* 根據id查詢索引
* @return
* @throws Exception
*/
@RequestMapping("getById")
public String getById() throws Exception {
SolrDocument document = client.getById("collection1", "1");
System.out.println(document);
return document.toString();
}
/**
* 綜合查詢
* @return
*/
@RequestMapping("search")
public Map<string>>> search(){/<string>
try {
SolrQuery params = new SolrQuery();
//查詢條件, 這裡的 q 對應 下面圖片標紅的地方
params.set("q", "手機");
//過濾條件
params.set("fq", "product_price:[100 TO 100000]");
//排序
params.addSort("product_price", SolrQuery.ORDER.asc);
//分頁
params.setStart(0);
params.setRows(20);
//默認域
params.set("df", "product_name");
//只查詢指定域
params.set("fl", "id,product_name,product_price");
//高亮
//打開開關
params.setHighlight(true);
//指定高亮域
params.addHighlightField("product_name");
//設置前綴
params.setHighlightSimplePre("");
//設置後綴
params.setHighlightSimplePost("");
QueryResponse queryResponse = client.query(params);
SolrDocumentList results = queryResponse.getResults();
long numFound = results.getNumFound();
System.out.println(numFound);
//獲取高亮顯示的結果, 高亮顯示的結果和查詢結果是分開放的
Map<string>>> highlight =/<string>
queryResponse.getHighlighting();
for (SolrDocument result : results) {
System.out.println(result.get("id"));
System.out.println(result.get("product_name"));
System.out.println(result.get("product_price"));
Map<string>> map = highlight.get(result.get("id"));/<string>
List<string> list = map.get("product_name");/<string>
System.out.println(list.get(0));
System.out.println("------------------");
System.out.println();
}
return highlight;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
"/<datasource>/<field>/<field>/<field>閱讀更多 瘋狂的亮亮 的文章