注意事項:首先要保證部署solr服務的Tomcat容器和檢索solr服務中數據的Tomcat容器,它們的端口號不能發生衝突,不然web程序是不可能運行起來的。前端
一:solr服務的端口號、我這裏的solr服務的tomcat容器的端口號已經修改成8083:java
二:檢索solr服務中數據的tomcat容器的端口號、我這裏是8080:
web
最後必需要保證2個容器能正常訪問。spring
需求:使用Solr實現電商網站中商品信息搜索功能,能夠根據關鍵字搜索商品信息,根據商品分類、價格過濾搜索結果,也能夠根據價格進行排序,實現分頁。apache
界面以下:spring-mvc
一、架構分析:tomcat
本身開發的應用:架構
Controller層的做用:獲取搜索條件,並響應搜索結果到前臺頁面。mvc
Service層的做用:接收Controller傳遞過來的參數,根據參數拼裝一個查詢條件,調用dao層方法,查詢商品數據;接收返回的商品列表和商品的總數量,根據每頁顯示的商品數量計算總頁數。app
Dao層的做用:接收Service層傳遞過來的參數,根據參數去檢索solr索引庫中的商品數據,返回查詢結果。
二、WEB工程的搭建(相關的jar必須得所有引入,環境搭建篇中已經註明了):
須要說明的幾點問題:
(a)、在springmvc核心配置文件中配置solr服務時,必定將solr服務的鏈接地址配置正確,不然沒法找到solr索引庫:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置註解掃描--> <context:component-scan base-package="com.jd"/> <!-- 配置註解驅動: 就至關於自動替咱們配置註解形式的處理器映射器和處理器適配器 --> <mvc:annotation-driven/> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 配置solrServer服務,供數據訪問層檢索數據使用: --> <bean id="solrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer"> <!-- 配置構造方法 --> <constructor-arg value="http://localhost:8083/solr/collection1"/> </bean> </beans>
(b)、在項目的web.xml配置文件中配置springmvc的前端控制器、post請求的亂碼解決等問題:
<!-- springMvc前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <!-- 解決post亂碼 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
三、各個開發層的代碼實現,程序中基本附帶註釋:
【Dao層】
1 package com.jd.dao; 2 3 import org.apache.solr.client.solrj.SolrQuery; 4 5 import com.jd.pojo.ResultModel; 6 7 /** 8 * 商品模塊Dao接口: 9 * @author zxz 10 * 11 */ 12 13 public interface ProductDao { 14 15 /** 16 * 根據檢索條件檢索solr服務上索引庫中的數據: 17 * @param solrQuery 18 * @return 19 * @throws Exception 20 */ 21 public ResultModel search(SolrQuery solrQuery) throws Exception; 22 23 }
1 package com.jd.dao; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import org.apache.solr.client.solrj.SolrQuery; 6 import org.apache.solr.client.solrj.SolrServer; 7 import org.apache.solr.client.solrj.response.QueryResponse; 8 import org.apache.solr.common.SolrDocument; 9 import org.apache.solr.common.SolrDocumentList; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.stereotype.Repository; 12 import com.jd.pojo.ProductModel; 13 import com.jd.pojo.ResultModel; 14 15 /** 16 * 商品模塊Dao層開發: 17 * 核心功能:接收Service層傳遞過來的參數,根據參數去檢索solr索引庫中的商品數據,返回查詢結果 18 * @author zxz 19 * 20 */ 21 @Repository 22 public class ProductDaoImpl implements ProductDao { 23 24 //注入solr服務(該solr服務在springmvc的核心配置文件中已經進行配置了): 25 @Autowired 26 private SolrServer solrServer; 27 28 //檢索solr服務上索引庫中的數據: 29 @Override 30 public ResultModel search(SolrQuery solrQuery) throws Exception { 31 //一、查詢並獲取響應結果: 32 QueryResponse response = solrServer.query(solrQuery); 33 34 //二、從響應中獲取結果集: 35 SolrDocumentList results = response.getResults(); 36 37 //三、處理結果集: 38 //專門用於存放響應結果集中的個個商品數據的集合 39 List<ProductModel> productList = new ArrayList<ProductModel>(); 40 //用於將檢索到的並處理好的數據封裝到ResultModel對象中,用於返回給Service層: 41 ResultModel resultModel = new ResultModel(); 42 //作非空校驗,若是檢索到的結果集不爲空的話,就進行處理並封裝結果數據: 43 if(results != null){ 44 //(1)、封裝查詢到的商品總數: 45 resultModel.setRecordCount(results.getNumFound()); 46 47 //(2)、遍歷響應中的結果集,並將數據一一封裝進ProductModel對象中: 48 for (SolrDocument document : results) { 49 //建立ProductModel對象: 50 ProductModel product = new ProductModel(); 51 //商品id: 52 product.setPid(String.valueOf(document.get("id"))); 53 //商品名稱: 54 product.setName(String.valueOf(document.get("product_name"))); 55 //商品價格: 56 if(String.valueOf(document.get("product_price"))!=null && 57 !"".equals(String.valueOf(document.get("product_price")))){ 58 product.setPrice(Float.valueOf(String.valueOf(document.get("product_price")))); 59 } 60 //商品圖片: 61 product.setPicture(String.valueOf(document.get("product_picture"))); 62 63 //將當前遍歷並封裝好的ProductModel對象添加到存放商品數據的集合中: 64 productList.add(product); 65 } 66 67 //循環處理並封裝好結果集以後,將存放商品數據的集合設置到ResultModel對象中: 68 resultModel.setProductList(productList); 69 } 70 71 //將封裝好的數據返回給Service層處理: 72 return resultModel; 73 } 74 }
【Service層】
1 package com.jd.service; 2 3 import com.jd.pojo.ResultModel; 4 5 /** 6 * 商品模塊Service層接口: 7 * @author zxz 8 * 9 */ 10 11 public interface ProductService { 12 13 /** 14 * 根據各類檢索條件去調用dao層的方法,獲得符合檢索條件的數據: 15 * @param queryString 16 * @param catalog_name 17 * @param price 18 * @param page 19 * @param sort 20 * @return 21 * @throws Exception 22 */ 23 public ResultModel search(String queryString, String catalog_name, 24 String price, Integer page, String sort) throws Exception; 25 26 }
1 package com.jd.service; 2 3 import org.apache.solr.client.solrj.SolrQuery; 4 import org.apache.solr.client.solrj.SolrQuery.ORDER; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Service; 7 import com.jd.dao.ProductDao; 8 import com.jd.pojo.ResultModel; 9 10 /** 11 * 商品模塊Service層開發: 12 * 核心功能:接收Controller傳遞過來的參數,根據參數拼裝一個查詢條件,調用dao層方法,查詢商品數據。 13 * 接收返回的商品列表和商品的總數量,根據每頁顯示的商品數量計算總頁數。 14 * @author zxz 15 * 16 */ 17 @Service 18 public class ProductServiceImpl implements ProductService { 19 20 //注入Dao: 21 @Autowired 22 private ProductDao productDao; 23 24 //定義常量,表明每頁顯示的商品條數: 25 private final static Integer PAGE_SIZE = 60; 26 27 //根據檢索條件獲得數據: 28 @Override 29 public ResultModel search(String queryString, String catalog_name, String price, Integer page, String sort) 30 throws Exception { 31 //一、封裝查詢條件對象,由於須要調用dao層的方法,dao層的檢索方法就須要一個solr服務的查詢條件對象: 32 SolrQuery solrQuery = new SolrQuery(); 33 34 //二、設置默認查詢的域(該默認的域已經在solrHome/collection1/conf/schema.xml配置文件中配置了業務域): 35 solrQuery.setQuery("product_keywords"); 36 37 //三、設置查詢的關鍵字: 38 if(queryString!=null && !"".equals(queryString)){ 39 solrQuery.setQuery(queryString); 40 }else{ 41 //若是沒有查詢的關鍵字,則默認查詢全部商品數據: 42 solrQuery.setQuery("*:*"); 43 } 44 45 //四、根據商品分類進行過濾: 46 if(catalog_name!=null && !"".equals(catalog_name)){ 47 //注意查詢語法:不要忽略":"號 48 solrQuery.addFilterQuery("product_catalog_name:" + catalog_name); 49 } 50 51 //五、根據商品價格進行過濾: 52 if(price!=null && !"".equals(price)){ 53 //由於傳遞過來的的商品價格的格式爲:100-300,因此須要切割並根據價格區間過濾商品數據: 54 String[] split = price.split("-"); 55 if(split!=null && split.length>1){ 56 //爲何判斷長度必須大於1,由於根據價格過濾須要最小值和最大值,必須有倆個值才能過濾成功 57 solrQuery.addFilterQuery("product_price:["+split[0]+" TO "+split[1]+"]"); 58 } 59 } 60 61 //六、按照商品價格排序展現商品數據: 62 if("1".equals(sort)){ 63 solrQuery.setSort("product_price",ORDER.asc); 64 }else{ 65 solrQuery.setSort("product_price",ORDER.desc); 66 } 67 68 //七、分頁查詢商品數據: 69 //首先校驗數據合法性,若是當前頁的值爲空或小於1,則默認開始查詢第一頁數據: 70 if(page == null){ 71 page = 1; 72 } 73 if(page < 1){ 74 page = 1; 75 } 76 //計算起始索引: 77 Integer startIndex = (page-1) * PAGE_SIZE; 78 //設置起始索引: 79 solrQuery.setStart(startIndex); 80 //設置每頁顯示的商品記錄數: 81 solrQuery.setRows(PAGE_SIZE); 82 83 //八、根據封裝後的SolrQuery查詢對象查詢商品數據: 84 ResultModel resultModel = productDao.search(solrQuery); 85 //設置當前頁數: 86 resultModel.setCurPage(page); 87 //計算總頁數: 88 Long pageCount = (long) Math.ceil((resultModel.getRecordCount()*1.0) / PAGE_SIZE); 89 //設置總頁數: 90 resultModel.setPageCount(pageCount); 91 92 return resultModel; 93 } 94 }
【Controller層】
1 package com.jd.controller; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Controller; 5 import org.springframework.ui.Model; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import com.jd.pojo.ResultModel; 8 import com.jd.service.ProductService; 9 10 /** 11 * 商品模塊: 12 * @author zxz 13 * 14 */ 15 16 @Controller 17 public class ProductController { 18 19 //注入Service接口: 20 @Autowired 21 private ProductService productService; 22 23 @RequestMapping("/list") 24 //根據條件和分頁信息檢索商品數據: 25 public String proList(String queryString, String catalog_name, 26 String price, Integer page, String sort,Model model) throws Exception{ 27 28 //調用service層的方法獲得檢索後的數據: 29 ResultModel resultModel = productService.search(queryString, catalog_name, price, page, sort); 30 31 //將檢索獲得的數據返回給頁面: 32 model.addAttribute("result", resultModel); //注意:這裏的名稱必須和jsp頁面上獲取數據的名稱保持一致 33 34 //回顯查詢條件: 35 model.addAttribute("queryString", queryString); //這裏的條件回顯時,名稱也必須和jsp頁面上獲取數據的名稱保持一致 36 model.addAttribute("catalog_name", catalog_name); 37 model.addAttribute("price", price); 38 model.addAttribute("sort", sort); 39 40 return "product_list"; 41 } 42 }
最後pojo類的數據模型截個圖給你們分享一下(案例所需的基本程序都在這裏了,但願能幫到你們,若是有什麼不對的地方望各位指教!!!):