2019-07-20

[if !supportLists]1. [endif]综合案例

[if !supportLists]1.1. [endif]需求

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

界面如下:

[if !vml]

[endif]

[if !supportLists]1.2. [endif]分析

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

[if !supportLists]1.2.1.      [endif]UI分析

[if !vml]

[endif]

[if !supportLists]1.2.2.      [endif]架构分析


[if !vml]

[endif]

架构分为:

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

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

(3)、数据库mysql


自己开发的应用

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

Service        封装查询条件,调用dao。

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

[if !supportLists]1.3. [endif]环境准备

Solr:4.10.3

Jdk环境:1.7.0_72(solr4.10 不能使用jdk1.7以下)

Ide环境:Eclipse

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

[if !supportLists]1.4.  [endif]代码实现

[if !supportLists]1.4.1. [endif]实现步骤

第一部分:SpringMVC框架搭建

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

第三部分:实现功能


[if !supportLists]1.4.2. [endif]实现步骤

[if !supportLists]1.4.2.1.           [endif]第一部分:SpringMVC框架搭建

[if !supportLists]1.4.2.1.1.    [endif]第一步:导入SpringMVC依赖包

--新建一个动态网站项目导入SpringMVC的Jar包

[if !vml]

[endif]


[if !supportLists]1.4.2.1.2.    [endif]第二步:创建一个请求页面

<%@pagelanguage="java"contentType="text/html;

  charset=UTF-8"


  pageEncoding="UTF-8"%>

<!DOCTYPEhtml>

<html>

<head>

<metacharset="UTF-8">

<title>Insert title here</title>

</head>

<body>


   "${pageContext.request.contextPath  }/say">say hello

</body>

</html>


[if !supportLists]1.4.2.1.3.    [endif]第三步:web.xml配置(入口)

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appxmlns: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>


[if !supportLists]1.4.2.1.4.    [endif]第四步:配置Spring配置文件

--mvc配置文件,spring-mvc.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="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:jspprefix="/"suffix=".jsp"/>

        </mvc:view-resolvers>



</beans>

--context配置文件,spring-context.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="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-scanbase-package="org.chu"></context:component-scan>



</beans>


[if !supportLists]1.4.2.1.5.    [endif]第五步:配置业务控制器

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;

    }


}


[if !supportLists]1.4.2.1.6.    [endif]第六步:配置返回页面

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

<%@pagelanguage="java"contentType="text/html;

  charset=UTF-8"


  pageEncoding="UTF-8"%>

<!DOCTYPEhtml>

<html>

<head>

<metacharset="UTF-8">

<title>Insert title here</title>

</head>

<body>

  你好世界

</body>

</html>

[if !supportLists]1.4.2.2.           [endif]第二部分:整合Spring与Solr


注意事项:

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


[if !supportLists]1.4.2.2.1.    [endif]第一步:修改Solr服务器端口

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


--Tomcat的conf/server.xml文件中,修改端口

--tomcat端口说明:

   8005:关机端口,修改为:8006

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

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


[if !supportLists]1.4.2.2.2.    [endif]第二步:导入Solr的连接依赖包

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

--日志处理包

[if !vml]

[endif]

--solrj依赖包

[if !vml]

[endif]


[if !supportLists]1.4.2.2.3.    [endif]第三步:加入Log4j的支持

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

[if !vml]

[endif]


[if !supportLists]1.4.2.2.4.    [endif]第四步:在spring-context.xml配置Solr

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

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

     <!--

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

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

</bean>


[if !supportLists]1.4.2.3.           [endif]第三部分:功能实现

[if !supportLists]1.4.2.3.1.    [endif]第一步:导入页面资源

前提:准备资料

[if !vml]

[endif]


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

结果如下:

[if !vml]

[endif]



[if !supportLists]1.4.2.3.2.    [endif]第二步:导入JSTL的支持

--我们发现页面报错。

[if !vml]

[endif]

--加入jstl的依赖包

[if !vml]

[endif]


[if !supportLists]1.4.2.3.3.    [endif]第三步:编写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;

  //补全get、set方法

}

--业务模型(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;

  //补全get、set方法


}


[if !supportLists]1.4.2.3.4.    [endif]第四步:获得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 {


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

        ResultModelresultModel=new  ResultModel();

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

        QueryResponseresponse = solrServer.query(query);

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

        SolrDocumentListresults = response.getResults();

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

        Listproducts=newArrayList<>();

        //设置高亮信息

        Map>> highlighting =  response.getHighlighting();

        for (SolrDocument solrDocument : results) {

            Productproduct=new  Product();

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

// 设置高亮信息

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

    }

}


[if !supportLists]1.4.2.3.5.    [endif]第五步:构造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 {

        //构建查询的条件

        SolrQueryquery=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>");



        ResultModelresultModel = productDAO.queryProduct(query);


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

        resultModel.setCurrentPage(curPage);


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

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

        resultModel.setPageCount((int)ceil);



        return resultModel;

    }


}



[if !supportLists]1.4.2.3.6.    [endif]第六步:构建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 {

            ResultModelresultModel = 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";

    }


}


[if !supportLists]1.4.2.3.7.    [endif]第七部:测试

[if !vml]

[endif]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 814评论 0 0
  • 学习资料下载 字节教育 Go语言初学者的学习资料 + Golang资料集Go最新资料汇总链接 第一节 ...
    Golang语言社区阅读 829评论 0 7
  • 走过古渡廊桥 灞柳烟云 走过太白栈道 丝路花雨 二零一七 就这么步履匆匆而又悄无声息地 渐渐离我们而去 还记得阡陌...
    桂花上酸菜阅读 204评论 14 21
  • Markdown的学习笔记 引用 普通引用在被引用的语句前添加>符号。> 被引用的语句 被引用的语句 嵌套引用: ...
    qin7zhen阅读 278评论 2 5
  • "群体的智慧低于个体的智慧" 去年的时候,一个PM推荐过我《乌合之众》,关于群体行为的研究,当时并没有太在意,因为...
    K猫阅读 1,641评论 4 6