springboot整合websocket、solr

一. 整合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">

data-config.xml

/<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>

8

<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>


分享到:


相關文章: