shiro实例

1             Solr案例实战

1.1          需求

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

界面如下:

 

1.2          分析

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

1.2.1         UI分析

 

1.2.2         架构分析

 

 

spring容器

表现层

springmvc

Service层

 

Dao层

Solr索引库

mysql数据库

商品信息

Tomcat

 

 

 

 

Solr服务

索引、搜索请求

架构分为:

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

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

(3)、数据库mysql

 

自己开发的应用

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

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

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

1.3          环境准备

Solr:4.10.3

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

Ide环境:Eclipse

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

1.4          功能开发

1.4.1         第一步:创建web工程,导入jar包

 

 

--导入的jar包说明:

Solrj的包

Solr服务的日志包

Spring的包(包含springmvc)

核心包  4个 core 、bean、context、expresstion

注解包  aop

Web包  web、webmvc

Commons日志包  common-logging

Jstl包

 

--导入静态资源和jsp页面说明:

静态资源放在webapp目录下,jsp页面放到/WEB-INF/目录下

 

1.4.2         第二步:Spring整合Solr、Springmvc

1.4.2.1     创建springmvc.xml

在config包下,创建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:mvc="http://www.springframework.org/schema/mvc"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

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

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

              http://www.springframework.org/schema/mvc

              http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd

              http://www.springframework.org/schema/context

              http://www.springframework.org/schema/context/spring-context-3.1.xsd

              http://www.springframework.org/schema/aop

              http://www.springframework.org/schema/aop/spring-aop-3.1.xsd

              http://www.springframework.org/schema/tx

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

       <!-- 配置扫描包 -->

       <context:component-scan base-package="cn.gzsxt" />

       <!-- 配置注解驱动 -->

       <mvc:annotation-driven />

      

       <!-- jsp视图解析器 -->

       <bean

              class="org.springframework.web.servlet.view.InternalResourceViewResolver">

              <!-- 前缀 -->

              <property name="prefix" value="/WEB-INF/jsp/"></property>

              <!-- 后缀 -->

              <property name="suffix" value=".jsp"></property>

       </bean>

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

              <constructor-arg value="http://localhost:8080/solr/solrCore0719"></constructor-arg>

       </bean>

 

</beans>

 

1.4.2.2     创建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>JD0719</display-name>

 

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

    </servlet>

    <servlet-mapping>

        <servlet-name>springmvc</servlet-name>

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

    </servlet-mapping>

    <filter>

        <filter-name>Character Encoding</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>Character Encoding</filter-name>

        <url-pattern>*.action</url-pattern>

    </filter-mapping>

</web-app>

 

1.4.3         第三步:整合测试

1.4.3.1     需求:

访问搜索页面。

 

1.4.3.2     创建PageController类

package cn.gzsxt.solr.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("page")String page){

        

       return page;

    }

}

 

1.4.3.3     注意事项

(1)Solr服务器要先开启。

(2)Solr服务器部署的Tomcat和本web应用的部署的Tomcat不是同一个。

 

(3)要同时启动两个Tomcat,要注意端口冲突问题。

 

1.4.3.4     修改Solr服务器的Tomcat的端口

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

--tomcat端口说明:

   8005:关机端口

   8080:默认服务端口

   8009:请求转向端口。

 

--注意:这三个端口都需要修改。不然启动会冲突

 

本次课程中,将solr的tomcat端口,修改为8888.

 

1.4.3.5     修改Springmvc.xml

--修改Solr服务的端口

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

              <constructor-arg value="http://localhost:8888/solr/solrCore0719"></constructor-arg>

       </bean>

 

 

 

1.4.3.6     访问搜索页面

地址:http://localhost:8080/solr-demo-02-jd/product_list.action

 

 

 

 

整合成功!!!

 

1.4.4         第四步:搜索功能实现

分析代码结构:

请求路径

list.action

请求方式

POST

请求参数

queryString、catalog_name、price、curPage、sort(共5个)

返回结果

定义Product 以及ProductModel

 

 

1.4.4.1     Pojo

1.4.4.1.1     分析

结合查询界面,分析得出:

--需要一个商品的pojo(Product),存放商品信息

--需要一个包装pojo(ResultModel),它包括商品列表信息、商品分页信息

1.4.4.1.2     创建Product类

public class Product {

    // 商品编号

    private String pid;

    // 商品名称

    private String name;

    // 商品分类名称

    private String catalog_name;

    // 价格

    private double price;

    // 商品描述

    private String description;

    // 图片名称

    private String picture;

}

 

1.4.4.1.3     创建ResultModel类

public class ResultModel {

    private List<Product> productList;

    // 商品总数

    private Long recordCount;

    // 总页数

    private int pageCount;

    // 当前页

    private int currentPage;

}

 

1.4.4.2     Dao

1.4.4.2.1     功能

接收service层传递过来的参数,根据参数查询索引库,返回查询结果。

 

1.4.4.2.2     创建ProductDao接口,定义一个查询方法

public interface ProductDao {

 

    //查询商品信息,包括分页信息

    public ResultModel queryProduct(SolrQuery query) throws Exception;

}

 

1.4.4.2.3     创建ProductDaoImpl,重新改查询方法

package cn.gzsxt.dao.impl;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

 

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.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

 

import cn.gzsxt.bean.Product;

import cn.gzsxt.bean.ResultModel;

import cn.gzsxt.dao.ProductDao;

 

@Repository

public class ProductDaoImpl implements ProductDao {

 

    @Autowired

    private HttpSolrServer server;

 

    @Override

    public ResultModel queryProduct(SolrQuery query) throws Exception {

       ResultModel result = new ResultModel();

       // 通过server查询索引库

       QueryResponse response = server.query(query);

       // 获得查询结果

       SolrDocumentList documentList = response.getResults();

       // 把查询结果总数设置到ResultModel

       result.setRecordCount(documentList.getNumFound());

 

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

       Product product = null;

       // 高亮信息

       Map<String, Map<String, List<String>>> highlighting = response

              .getHighlighting();

       for (SolrDocument solrDocument : documentList) {

           product = new Product();

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

 

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

 

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

                  "product_name");

           if (list != null)

              prodName = list.get(0);

 

           product.setName(prodName);

           product.setCatalog_name((String) solrDocument

                  .get("product_catalog_name"));

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

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

 

           productList.add(product);

       }

 

       // 把商品列表放到ResultMap

       result.setProductList(productList);

       return result;

    }

 

}

 

1.4.4.3     Service

1.4.4.3.1     功能分析

接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。

接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。

1.4.4.3.2     创建ProductService接口,定义一个查询方法

public interface ProductService {

    public ResultModel queryProduct(String queryString, String cataName,

           String price, String sort, Integer curPage) throws Exception;

}

1.4.4.3.3     创建ProductServiceImpl类,重写改查询方法

package cn.gzsxt.service.impl;

 

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

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

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

import org.springframework.stereotype.Service;

 

import cn.gzsxt.dao.ProductDao;

import cn.gzsxt.service.ProductService;

import cn.gzsxt.vo.ResultModel;

 

@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(!"".equals(queryString)&& null != queryString){

            query.setQuery(queryString);

        }else{

            query.setQuery("*:*");

        }

       

        //判断过滤条件是否为空

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

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

        }

       

        //判断商品价格是否为空

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

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

            if(prices.length == 2){

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

            }

        }

       

        //设置排序

        if("1".equals(sort)){

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

        }else {

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

        }

       

        //设置分页信息

        if(null == curPage){

            curPage = 1;

        }

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

        query.setRows(20);  //每页20条数据

       

        //设置默认搜索域

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

       

        query.setHighlight(true);

        query.addHighlightField("product_name");

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

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

       

        ResultModel result = productDao.queryProduct(query);

        result.setCurrentPage(curPage);

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

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

        result.setPageCount((int)ceil);

       

        return result;

    }

}

 

1.4.4.4     Controller

1.4.4.4.1     创建ProductController类,定义查询接口

package cn.gzsxt.controller;

 

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 cn.gzsxt.service.ProductService;

import cn.gzsxt.vo.ResultModel;

 

@Controller

public class ProductController {

 

    @Autowired

    private ProductService productService;

   

    @RequestMapping("/list.action")

    public String queryProduct(String queryString, String catalog_name,

            String price, String sort, Integer curPage, ModelMap model)

            throws Exception {

 

        ResultModel resultModel = productService.queryProduct(queryString, catalog_name,

                price, sort, curPage);

        model.addAttribute("result", resultModel);

        model.addAttribute("queryString", queryString);

        model.addAttribute("catalog_name", catalog_name);

        model.addAttribute("price", price);

        model.addAttribute("sort", sort);

        model.addAttribute("page", curPage);

       

        return "product_list";

    }

}

 

 

1.4.4.5     测试搜索功能

地址:http://localhost:8080/solr-demo-02-jd/list.action

 
posted @ 2019-07-20 22:38  于陆  阅读(443)  评论(0编辑  收藏  举报