壹立方商城----实现商品搜索功能

1.效果展示

启动项目,进入淘淘商城首页,我们搜索小米

 

壹立方商城----实现商品搜索功能_第1张图片

然后商品搜索页面就会展示,所有搜索到的商品(图片无法显示,是因为图片地址失效了,可以显示的是我自己添加的)

搜索时,会有关键字分词+高亮壹立方商城----实现商品搜索功能_第2张图片

还有分页效果壹立方商城----实现商品搜索功能_第3张图片

2.功能分析

我们在e3-portal-web首页展示中分析,输入关键字后,点击搜索后到底发生了什么。

由于搜索框是通用的,在搜索结果页面,上面也会有搜索框,所以搜索相关代码在header.jsp

壹立方商城----实现商品搜索功能_第4张图片

在header.jsp中,用户点击搜索,或者按回车(event.keyCode==13),会将id=key提交到search函数。search函数在header.jsp唯一引入的base-v1.js中壹立方商城----实现商品搜索功能_第5张图片

我们搜索search函数,发现在第33行。encodeURIComponent(document.getElementById(a).value)获取到id=a(也就是key)的值,进行url编码就是"%xx%xxx"这种,然后拼接到"http://localhost:8085/search.html?q="后面。window.location.href表示跳转至url。
壹立方商城----实现商品搜索功能_第6张图片

所以我们知道,当用户点击搜索时,跳转"http://localhost:8085/search.html?q=xxx",并携带查询关键字q,所以我们只需要,接收关键字,从索引库查询即可。这里有个隐含的参数 "page页码",在搜索结果页面用于分页,在搜索页面仅仅是搜索,并不设置及

,所以默认page=1,搜索时默认搜索第一页。

3.dao层

3.1功能分析

访问索引库的类。定义一些通用的数据访问方法。

业务逻辑就是查询索引库。

参数:SolrQuery对象

业务逻辑:

  1. 根据Query对象进行查询。
  2. 返回查询结果。包括List、查询结果的总记录数。

需要把返回结果封装到pojo中,至少包含两个属性:List、Long recordCount

再包含一个总页数。

创建如下SearchResult对象,放入e3-common中

SearchResult.java

package cn.e3mall.common.pojo;

import java.io.Serializable;
import java.util.List;

public class SearchResult implements Serializable {

	private long recordCount;//总记录数
	private int totalPages;//总页数
	private List itemList;//搜索结果列表
	public long getRecordCount() {
		return recordCount;
	}
	public void setRecordCount(long recordCount) {
		this.recordCount = recordCount;
	}
	public int getTotalPages() {
		return totalPages;
	}
	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}
	public List getItemList() {
		return itemList;
	}
	public void setItemList(List itemList) {
		this.itemList = itemList;
	}
	
}

3.2创建SearchDao

由于搜索功能只在搜索工程中用到,可以不写接口,只写类。返回值:SearchResult

在e3-search-service中创建com.taotao.search.dao包,在包中SearchDao创建用于访问索引库

从service层接收封装好的SolrQuery查询索引库,获取QueryResponse,从QueryResponse获取SolrDocumentList,在从SolrDocumentList中获取solr业务域中的字段,并取出service层封装的高亮,封装成List,放入SearchResult中
SearchDao.java

package cn.e3mall.search.dao;

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.SolrServer;
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 org.springframework.web.bind.annotation.ResponseBody;

import cn.e3mall.common.pojo.SearchItem;
import cn.e3mall.common.pojo.SearchResult;

/**
 * 商品搜索dao
 * 

* Title: SearchDao *

* * @version 1.0 */ @Repository public class SearchDao { @Autowired private SolrServer solrServer; /** * 根据SolrQuery查询索引库,封装SearchResult的itemList、recordCount *

* Title: search *

*

* Description: *

* * @param query * @return */ public SearchResult search(SolrQuery query) throws Exception { // 1、根据query查询索引库 QueryResponse queryResponse = solrServer.query(query); // 2、获取商品列表 SolrDocumentList solrDocumentList = queryResponse.getResults(); // 3、取查询结果总记录数 long numFound = solrDocumentList.getNumFound(); SearchResult result = new SearchResult(); result.setRecordCount(numFound); // 取商品列表,需要取高亮显示 Map>> highlighting = queryResponse.getHighlighting(); // 封装List List itemList = new ArrayList<>(); for (SolrDocument solrDocument : solrDocumentList) { SearchItem item = new SearchItem(); item.setId((String) solrDocument.get("id")); item.setCategory_name((String) solrDocument.get("item_category_name")); item.setImage((String) solrDocument.get("item_image")); item.setPrice((long) solrDocument.get("item_price")); item.setSell_point((String) solrDocument.get("item_sell_point")); // 取高亮显示 List list = highlighting.get(solrDocument.get("id")).get("item_title"); String title = ""; if (list != null && list.size() > 0) { title = list.get(0); } else { title = (String) solrDocument.get("item_title"); } item.setTitle(title); // 添加到商品列表 itemList.add(item); } result.setItemList(itemList); // 返回结果 return result; } }

4.service层

4.1功能分析

参数:queryString:查询条件

      Page:页码

      Rows:每页显示的记录数。

业务逻辑:

  1. 创建一个SolrQuery对象。
  2. 设置查询条件
  3. 设置分页条件
  4. 需要指定默认搜索域。
  5. 设置高亮
  6. 执行查询,调用SearchDao。得到SearchResult
  7. 需要计算总页数。
  8. 返回SearchResult

4.2创建service接口

在e3-search-interface的SearchService创建接口

壹立方商城----实现商品搜索功能_第7张图片

SearchService.java

package cn.e3mall.search.service;

import cn.e3mall.common.pojo.SearchResult;

public interface SearchService {
	/**
	 * 根据查询条件查询
	 * @param queryString
	 * @param page
	 * @param rows
	 * @return
	 * @throws Exception
	 */
	SearchResult search(String keyword, int page, int rows)  throws Exception;
}

4.3创建service实现类

在e3-search-service的cn.e3mall.search.service.impl包的SearchServiceImpl实现接口

要注意注入searchDao依赖

设置查询索引库的主查询条件和分页条件,还需要设置高亮,最后获取SearchResult封装总页数

package cn.e3mall.search.service.impl;

import org.apache.solr.client.solrj.SolrQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.e3mall.common.pojo.SearchResult;
import cn.e3mall.search.dao.SearchDao;
import cn.e3mall.search.service.SearchService;

/**
 * 商品搜索Service
 * 

* Title: SearchServiceImpl *

* * @version 1.0 */ @Service public class SearchServiceImpl implements SearchService { @Autowired private SearchDao searchDao; @Override public SearchResult search(String keyword, int page, int rows) throws Exception { // 创建一个SolrQuery对象 SolrQuery query = new SolrQuery(); // 设置查询条件 query.setQuery(keyword); // 设置分页条件 if (page <= 0) page = 1; query.setStart((page - 1) * rows); query.setRows(rows); // 设置默认搜索域 query.set("df", "item_title"); // 开启高亮显示 query.setHighlight(true); query.addHighlightField("item_title"); query.setHighlightSimplePre(""); query.setHighlightSimplePost(""); // 调用dao执行查询 SearchResult searchResult = searchDao.search(query); // 计算总页数 long recordCount = searchResult.getRecordCount(); int totalPage = (int) (recordCount / rows); if (recordCount % rows > 0) totalPage++; // 添加到返回结果 searchResult.setTotalPages(totalPage); // 返回结果 return searchResult; } }

4.4applicationContext-service.xml

dao层包扫描与发布service服务

配置包扫面的时候,可以扩大包扫描的范围



5.表现层

5.1导入搜索结果静态页面

壹立方商城----实现商品搜索功能_第8张图片

5.2引入服务

壹立方商城----实现商品搜索功能_第9张图片

5.3创建controller


请求的url:/search

参数:

1、q 查询条件。

2、page 页码。默认为1

返回值:

逻辑视图,返回值。String。

业务逻辑:

接收参数
调用服务查询商品列表
把查询结果传递给页面。需要参数回显。
在e3-search-web创建cn.e3mall.search.controller包,在cn.e3mall.search.controller创建SearchController

cn.e3mall.search.controller.SearchController.java

package cn.e3mall.search.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import cn.e3mall.common.pojo.SearchResult;
import cn.e3mall.search.service.SearchService;

/**
 * 商品搜索Controller
 * 

* Title: SearchController *

* * @version 1.0 */ @Controller public class SearchController { @Autowired private SearchService searchService; @Value("${SEARCH_RESULT_ROWS}") private Integer SEARCH_RESULT_ROWS; @RequestMapping("/search") public String searchItemList(String keyword, @RequestParam(defaultValue = "1") Integer page, Model model) throws Exception { //get请求中文乱码解决 keyword = new String(keyword.getBytes("iso-8859-1"), "utf-8"); // 查询商品列表 SearchResult searchResult = searchService.search(keyword, page, SEARCH_RESULT_ROWS); // 把结果传递给页面 model.addAttribute("query", keyword); model.addAttribute("totalPages", searchResult.getTotalPages()); model.addAttribute("page", page); model.addAttribute("recourdCount", searchResult.getRecordCount()); model.addAttribute("itemList", searchResult.getItemList()); // 返回逻辑视图 return "search"; } }

5.4配置分页大小

分页大小放入配置文件中

/e3-search-web/src/main/resources/conf/resource.properties

#搜索结果每页显示的记录数
SEARCH_RESULT_ROWS=60

还需要在springmvc.xml加载配置文件


5.5测试

发现无法翻页。

翻页处理:在e3-search-web工程中:修改如下:

修改url的端口,在这里可以看到前面说的page参数

壹立方商城----实现商品搜索功能_第10张图片

5.6图片无法显示
这里说的是有图片的情况无法显示。

数据库中保存的图片是以逗号分隔的url列表,只需要展示第一张图片即可。

方法:

  1. 向索引库中添加文档时,只取第一张写入索引库
  2. 从文档列表转换为商品列表时可以取一张。
  3. 在jsp中对列表拆分,只取一张展示。

可以在SearchItem中添加一个getImages方法:
壹立方商城----实现商品搜索功能_第11张图片

public String[] getImages() {
		if(this.image != null&&!this.image.equals("")) {
			String[] strings = this.image.split(",");
			return strings;
		}
		return null;
	}

使用el表达式执行方法,获取第一张图片壹立方商城----实现商品搜索功能_第12张图片

 

 

 

 

 

 

参考文章

原文:https://blog.csdn.net/pdsu161530247/article/details/81974760

你可能感兴趣的:(壹立方商城项目)