目录
1、原型分析
2、系统架构
3、工程搭建
3.1 创建web工程
3.2 导入jar包
spring mvc的相关jar包
solrJ的jar包
Example\lib\ext下的jar包
3.3 配置相关信息
3.3.1 springmvc.xml
<?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: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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="cn.chuantao"/>
<!-- 配置注解驱动,如果配置此标签可以不用配置处理器映射器和适配器 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- SolrServer的配置 -->
<bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
<!-- index=0 代表调用有一个构造参数的solrServer的构造方法 -->
<constructor-arg index="0" value="http://localhost:8080/solr"/>
</bean>
</beans>
3.3.2 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>solr_jd_search</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置前段控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 指定springmvc配置文件的路径
如果不指定默认为:/WEB-INF/${servlet-name}-servlet.xml
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</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>
</web-app>
3.4 Dao层
功能:接收service层传递过来的参数,根据参数查询索引库,返回查询结果。
参数:SolrQuery对象(查询条件的对象)
需要返回的数据:一个商品列表List<ProductModel>,还需要返回查询结果的总数量。
返回:ResultModel(封装到一个结果pojo类中)
方法定义:ResultModel queryProduct(SolrQuery query) throws Exception;
3.4.1 创建pojo对象
封装商品属性的productModel类
public class ProductModel {
// 商品编号
private String pid;
// 商品名称
private String name;
// 商品分类名称
private String catalog_name;
// 价格
private float price;
// 商品描述
private String description;
// 图片名称
private String picture;
}
返回jsp结果的ResultModel类
public class ResultModel {
// 商品列表
private List<ProductModel> productList;
// 商品总数
private Long recordCount;
// 总页数
private int pageCount;
// 当前页
private int curPage;
}
3.4.2 dao实现类
@Repository
public class SolrDaoImp implements SolrDao {
// 注入solrServer服务器
@Autowired
private SolrServer solrServer;
/**
* solrQuery:查询条件
* ResultModel:返回封装的结果
*/
public ResultModel queryProduct(SolrQuery solrQuery) throws Exception {
//查询并获取查询响应
QueryResponse queryResponse = solrServer.query(solrQuery);
// 从响应中获取查询结果集
SolrDocumentList results = queryResponse.getResults();
// 创建返回结果对象
ResultModel resultModel = new ResultModel();
// 创建封装商品的存储集合
List<ProductModel> list = new ArrayList<ProductModel>();
// 遍历结果集
if(results!=null){
// 根据查询总结果集设置总记录数(总条数)
resultModel.setRecordCount(results.getNumFound());
// 遍历结果集
for (SolrDocument doc : results) {
// 创建商品对象
ProductModel productModel = new ProductModel();
// 使用第二种方式进行转换
productModel.setPid(String.valueOf(doc.get("id")));
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
if(highlighting != null){
List<String> listList = highlighting.get(doc.get("id")).get("product_name");
if(listList != null && listList.size() > 0){
productModel.setName(listList.get(0));
} else {
productModel.setName(String.valueOf(doc.get("product_name")));
}
} else {
// 封装商品对象 采用 (string强转的方式)
productModel.setName((String) doc.get("product_name"));
}
if(doc.get("product_price") != null && !"".equals(doc.get("product_price"))){
productModel.setPicture(String.valueOf(doc.get("product_picture")));
}
productModel.setCatalog_name(String.valueOf(doc.get("product_catalog_name")));
productModel.setPicture(String.valueOf(doc.get("product_picture")));
list.add(productModel);
}
resultModel.setProductList(list);
}
return resultModel;
}
}
3.5 service
功能:接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。
参数:
1、查询条件:字符串
2、商品分类的过滤条件:商品的分类名称,字符串
3、商品价格区间:传递一个字符串,满足格式:“0-100、101-200、201-*”
4、排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序
5、分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。
业务逻辑
- 根据参数创建查询对象
- 调用dao执行查询。
- 根据总记录数计算总页数。
返回值:ResultModel
方法定义:ResultModel queryProduct(String queryString, String caltalog_name, String price, String sort, Integer page) throws Exception;
@Service
public class SolrServiceImp implements SolrService {
@Autowired
private SolrDao solrDao;
private static final Integer PAGE_SIZE = 60;
@Override
public ResultModel queryProduct(String queryString, String catalog_name, String price, String sort, Integer page)
throws Exception {
//创建查询条件对象
SolrQuery solrQuery = new SolrQuery();
//设置默认搜索域
solrQuery.set("df", "product_keywords");
//设置查询关键字
if(queryString != null && !"".equals(queryString)){
solrQuery.setQuery(queryString);
} else {
solrQuery.setQuery("*:*");
}
//设置过滤条件按照分类名称进行过滤
if(catalog_name != null && !"".equals(catalog_name)){
solrQuery.addFilterQuery("product_catalog_name:" + catalog_name);
}
//设置过滤条件按照价格进行过滤
if(price != null && !"".equals(price)){
String[] split = price.split("-");
if(split != null && split.length > 1){
solrQuery.addFilterQuery("product_price:["+split[0]+" TO "+split[1]+"]");
}
}
//设置排序
if("1".equals(sort)){
solrQuery.addSort("product_price", ORDER.asc);
} else {
solrQuery.addSort("product_price", ORDER.desc);
}
//设置分页
if(page == null){
page = 1;
}
Integer start = (page - 1) * PAGE_SIZE;
//从第几天记录开始查
solrQuery.setStart(start);
//每页显示多少条
solrQuery.setRows(PAGE_SIZE);
//设置高亮显示
solrQuery.setHighlight(true);
//设置高亮显示的域
solrQuery.addHighlightField("product_name");
//设置高亮前缀
solrQuery.setHighlightSimplePre("<span style=\"color:red\">");
//设置高亮后缀
solrQuery.setHighlightSimplePost("</span>");
//查询返回结果
ResultModel resultModel = solrDao.queryProduct(solrQuery);
resultModel.setCurPage(Long.parseLong(page.toString()));
//计算总页数
Long pageCount = resultModel.getRecordCount() / PAGE_SIZE;
if(resultModel.getRecordCount() % PAGE_SIZE > 0){
pageCount ++;
}
resultModel.setPageCount(pageCount);
return resultModel;
}
3.6 Controller
功能:接收页面传递过来的参数调用service查询商品列表。将查询结果返回给jsp页面,还需要查询参数的回显。
参数:
1、查询条件:字符串
2、商品分类的过滤条件:商品的分类名称,字符串
3、商品价格区间:传递一个字符串,满足格式:“0-100、101-200、201-*”
4、排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序
5、分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。
6、Model:相当于request。
返回结果:String类型,就是一个jsp的名称。
String queryProduct(String queryString, String caltalog_name, String price, String sort, Integer page, Model model) throws Exception;