• Solr综合案例深入练习


    1. 综合案例

    1.1. 需求

    使用Solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商品信息,也可以根据价格进行排序,并且实现分页功能。

    界面如下:

    1.2. 分析

    开发人员需要的文档静态页面(根据UI设计由美工给出)、数据库设计、原型设计

    1.2.1. UI分析

    1.2.2. 架构分析

     

     

    架构分为

    1)、solr服务器。(已经做完,同入门示例)

    2)、自己开发的应用(重点)

    3)、数据库mysql

     

    自己开发的应用

    Controller      负责和前端页面进行请求和响应的交互

    Service        封装查询条件,调用dao

    Dao           搜索索引库,返回搜索结果。

    1.3. 环境准备

    Solr4.10.3

    Jdk环境1.7.0_72solr4.10 不能使用jdk1.7以下

    Ide环境Eclipse

    Web服务器servlet容器):Tomcat 7+

    1.4. 代码实现

    1.4.1. 实现步骤

    第一部分:SpringMVC框架搭建

    第二部分:整合SpringSolr Solr服务已经搭建好了)

    第三部分:实现功能

     

    1.4.2. 实现步骤

    1.4.2.1. 第一部分:SpringMVC框架搭建

    1.4.2.1.1. 第一步:导入SpringMVC依赖包

    --新建一个动态网站项目导入SpringMVCJar

     

    1.4.2.1.2. 第二步:创建一个请求页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

    <!DOCTYPE html>

    <html>

    <head>

    <meta charset="UTF-8">

    <title>Insert title here</title>

    </head>

    <body>

       

       <a href="${pageContext.request.contextPath }/say">say hello</a>

    </body>

    </html>

     

    1.4.2.1.3. 第三步:web.xml配置(入口)

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns="http://xmlns.jcp.org/xml/ns/javaee"

    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

    id="WebApp_ID" version="3.1">

    <display-name>solr-demo-02-jd</display-name>

    <!-- 配置编码过滤器 -->

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

    <!-- 核心控制器 -->

    <servlet>

    <servlet-name>dispatcherServlet</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- 读取指定的配置文件 -->

    <init-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:spring-*.xml</param-value>

    </init-param>

    <!-- 随web server启动 -->

    <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

    <servlet-name>dispatcherServlet</servlet-name>

    <url-pattern>/</url-pattern>

    </servlet-mapping>

     

    </web-app>

     

    1.4.2.1.4. 第四步:配置Spring配置文件

    --mvc配置文件,spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd

    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

     

    <!-- 启动注解默认支持 -->

    <mvc:annotation-driven />

    <!-- 放开默认静态资源访问 -->

    <mvc:default-servlet-handler/>

     

    <!-- 配置视图解释器 -->

    <mvc:view-resolvers>

      <mvc:jsp prefix="/" suffix=".jsp"/>

    </mvc:view-resolvers>

     

     

    </beans>

    --context配置文件,spring-context.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:context="http://www.springframework.org/schema/context"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

     

    <!-- 扫描组件配置 -->

    <context:component-scan base-package="org.chu"></context:component-scan>

     

     

    </beans>

     

    1.4.2.1.5. 第五步:配置业务控制器

    package org.chu.controller;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.PathVariable;

    import org.springframework.web.bind.annotation.RequestMapping;

     

    @Controller

    public class PageController {

     

    @RequestMapping(value="/{page}")

    public String showPage(@PathVariable String page) {

    System.out.println("-HelloWorld:"+page);

    return page;

    }

     

    }

     

    1.4.2.1.6. 第六步:配置返回页面

    --返回页面为:/say.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

    <!DOCTYPE html>

    <html>

    <head>

    <meta charset="UTF-8">

    <title>Insert title here</title>

    </head>

    <body>

      你好世界

    </body>

    </html>

    1.4.2.2. 第二部分:整合SpringSolr

     

    注意事项:

    必须要将SolrTomcat服务器的端口配置与项目运行的Tomcat的端口不一样。因为如果在同一个电脑上同时运行两个Tomcat,端口不修改就会冲突。

     

    1.4.2.2.1. 第一步:修改Solr服务器端口

    前提:Solr服务器已经准备好。

     

    --Tomcatconf/server.xml文件中,修改端口

    --tomcat端口说明:

       8005:关机端口 修改为:8006

       8080:默认服务端口修改为 8888

       8009:请求转向端口修改为:8010

     

    1.4.2.2.2. 第二步:导入Solr的连接依赖包

    --将以下的jar 加入到项目的WEB-INF/lib里面。

    --日志处理包

    --solrj依赖包

     

    1.4.2.2.3. 第三步:加入Log4j的支持

    classpath根目录加入lo4j.properties。该文件可以在solr的包里面找到

     

     

    1.4.2.2.4. 第四步:在spring-context.xml配置Solr

    <!-- 配置Solr整合的连接对象 -->

    <bean name="solrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">

     <!-- 通过构造方法指定请求的路径 -->

    <constructor-arg index="0" value="http://localhost:8888/solr/soreCore0225" />

    </bean>

     

    1.4.2.3. 第三部分:功能实现

    1.4.2.3.1. 第一步:导入页面资源

    前提:准备资料

     

     

    --将准备的资料放在webapp,网站根目录。并且删除原来测试的页面,test.jsp以及say.jsp

    结果如下:

     

     

     

    1.4.2.3.2. 第二步:导入JSTL的支持

    --我们发现页面报错。

     

    --加入jstl的依赖包

     

     

    1.4.2.3.3. 第三步:编写JavaBean

    --编写Product实体类

    package org.chu.pojo;

     

    public class Product {

    // 商品编号

    private String pid;

    // 商品名称

    private String name;

    // 商品分类名称

    private String catalogName;

    // 价格

    private double price;

    // 商品描述

    private String description;

    // 图片名称

    private String picture;

      //补全getset方法

    }

    --业务模型(Value Object VO),编写ResultModel业务模型

    package org.chu.pojo;

     

    import java.util.List;

     

    public class ResultModel {

     

    private List<Product> productList;

    // 商品总数

    private Long recordCount;

    // 总页数

    private int pageCount;

    // 当前页

    private int currentPage;

      //补全getset方法

     

    }

     

    1.4.2.3.4. 第四步:获得Solr的数据

    package org.chu.dao.impl;

    import java.util.ArrayList;

    import java.util.List;

    import org.apache.solr.client.solrj.SolrQuery;

    import org.apache.solr.client.solrj.impl.HttpSolrServer;

    import org.apache.solr.client.solrj.response.QueryResponse;

    import org.apache.solr.common.SolrDocument;

    import org.apache.solr.common.SolrDocumentList;

    import org.chu.dao.ProductDAO;

    import org.chu.pojo.Product;

    import org.chu.pojo.ResultModel;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Repository;

    @Repository

    public class ProductDAOImpl implements ProductDAO{

    @Autowired

    private HttpSolrServer solrServer;

    @Override

    public ResultModel queryProduct(SolrQuery query) throws Exception {

     

    //创建一个返回的业务模型对象

    ResultModel resultModel=new ResultModel();

    //第一步:获得Solr响应对象

    QueryResponse response = solrServer.query(query);

    //第二步:获得返回的结果集

    SolrDocumentList results = response.getResults();

    //第三步:将SolrDocumentList集合对象转成List<Product>

    List<Product> products=new ArrayList<>();

    // 设置高亮信息

    Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

    for (SolrDocument solrDocument : results) {

    Product product=new Product();

    product.setPid((String)solrDocument.get("id"));

    // 设置高亮信息

    List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");

     

    String prodName = (String) solrDocument.get("product_name");

    if (list != null)prodName = list.get(0);

    product.setName(prodName);

    product.setCatalogName((String) solrDocument.get("product_catalog_name"));

    product.setPicture((String) solrDocument.get("product_picture"));

    product.setDescription((String) solrDocument.get("product_description"));

    product.setPrice((Double) solrDocument.get("product_price"));

    products.add(product);

    }

    //第四步:将数据封装到ResultModel

    //总记录书

    resultModel.setRecordCount(results.getNumFound());

    //查询的的结果

    resultModel.setProductList(products);

    return resultModel;

    }

    }

     

    1.4.2.3.5. 第五步:构造Service

    package org.chu.service.impl;

     

    import org.apache.solr.client.solrj.SolrQuery;

    import org.apache.solr.client.solrj.SolrQuery.ORDER;

    import org.chu.dao.ProductDAO;

    import org.chu.pojo.ResultModel;

    import org.chu.service.ProductService;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Service;

     

    @Service

    public class ProductServiceImpl implements ProductService {

     

    @Autowired

    private ProductDAO productDAO;

     

    @Override

    public ResultModel queryProduct(String queryString, String cataName, String price, String sort, Integer curPage)

    throws Exception {

    //构建查询的条件

    SolrQuery query=new SolrQuery();

     

    //判断关键字不为空

    if (queryString!=null&&!"".equals(queryString)) {

     

    query.set("q", queryString);

    }else {

    query.set("q", "*:*");

    }

     

    //增加过滤条件

    if (cataName!=null&&!"".equals(cataName)) {

    query.addFilterQuery("product_catalog_name:"+cataName);

    }

     

    //价格过滤

    if (price!=null&&!"".equals(price)) {

    String[] prices = price.split("-");

    query.addFilterQuery("product_price:[ "+prices[0]+" TO "+prices[1]+" ]");

    }

     

    //排序,1:desc ,非1就,asc

    if (sort!=null&&sort.equals("1")) {

    query.setSort("product_price", ORDER.desc);

    }else{

    query.setSort("product_price", ORDER.asc);

    }

     

    //设置分页

    //如果没有值,就为第一页

    if (curPage==null) {

    curPage=1;

    }

    //设置查询的开始位置

    query.setStart((curPage-1)*20);

    //设置每页记录数

    query.setRows(20);

     

     

    query.set("df", "product_name");

     

    //高亮分词设置

    query.setHighlight(true);

    //设置高亮的字段

    query.addHighlightField("product_name");

    //通过标签设置颜色

     

    //开始标签

    query.setHighlightSimplePre("<font style="color:red">");

    query.setHighlightSimplePost("</font>");

     

     

    ResultModel resultModel = productDAO.queryProduct(query);

     

    //返回结果后,封装请求的数据到业务模型里面

    resultModel.setCurrentPage(curPage);

     

    // 总页数 = 总数量 / 每页数据条数  结果向上取整

    double ceil = Math.ceil(resultModel.getRecordCount().doubleValue()/20);

    resultModel.setPageCount((int)ceil);

     

     

    return resultModel;

    }

     

    }

     

     

    1.4.2.3.6. 第六步:构建Controller

    package org.chu.controller;

     

    import org.chu.pojo.ResultModel;

    import org.chu.service.ProductService;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.ModelMap;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

     

    @Controller

    public class ProductController {

     

    @Autowired

    private ProductService productService;

     

    @RequestMapping(value="/list")

    public String list(String queryString, @RequestParam("catalog_name") String catalogName,String price, String sort, Integer curPage, ModelMap model) {

    try {

    ResultModel resultModel = productService.queryProduct(queryString, catalogName, price, sort, curPage);

    model.addAttribute("result", resultModel);

     

    model.addAttribute("queryString", queryString);

    model.addAttribute("catalog_name", catalogName);

    model.addAttribute("price", price);

    model.addAttribute("sort", sort);

    model.addAttribute("page", curPage);

     

    } catch (Exception e) {

    e.printStackTrace();

    }

     

     

      return "product_list";

    }

     

    }

     

    1.4.2.3.7. 第七部:测试

     

     

  • 相关阅读:
    C++界面库(十几种,很全)
    前端框架
    Asp.Net Web Api 接口,拥抱支持跨域访问。
    WEB控件
    MVC之验证
    AJAX跨域调用ASP.NET MVC或者WebAPI服务
    VS生产的编辑方法和编辑窗体
    DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计?
    Redis简介与简单安装
    Cocos2d-x 3.1.1开发环境
  • 原文地址:https://www.cnblogs.com/aknife/p/11219034.html
Copyright © 2020-2023  润新知