启动项目,进入淘淘商城首页,我们搜索小米
然后商品搜索页面就会展示,所有搜索到的商品(图片无法显示,是因为图片地址失效了,可以显示的是我自己添加的)
我们在e3-portal-web首页展示中分析,输入关键字后,点击搜索后到底发生了什么。
由于搜索框是通用的,在搜索结果页面,上面也会有搜索框,所以搜索相关代码在header.jsp
在header.jsp中,用户点击搜索,或者按回车(event.keyCode==13),会将id=key提交到search函数。search函数在header.jsp唯一引入的base-v1.js中
我们搜索search函数,发现在第33行。encodeURIComponent(document.getElementById(a).value)获取到id=a(也就是key)的值,进行url编码就是"%xx%xxx"这种,然后拼接到"http://localhost:8085/search.html?q="后面。window.location.href表示跳转至url。
所以我们知道,当用户点击搜索时,跳转"http://localhost:8085/search.html?q=xxx",并携带查询关键字q,所以我们只需要,接收关键字,从索引库查询即可。这里有个隐含的参数 "page页码",在搜索结果页面用于分页,在搜索页面仅仅是搜索,并不设置及
,所以默认page=1,搜索时默认搜索第一页。
访问索引库的类。定义一些通用的数据访问方法。
业务逻辑就是查询索引库。
参数:SolrQuery对象
业务逻辑:
需要把返回结果封装到pojo中,至少包含两个属性:List
再包含一个总页数。
创建如下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;
}
}
由于搜索功能只在搜索工程中用到,可以不写接口,只写类。返回值:SearchResult
在e3-search-service中创建com.taotao.search.dao包,在包中SearchDao创建用于访问索引库
从service层接收封装好的SolrQuery查询索引库,获取QueryResponse,从QueryResponse获取SolrDocumentList,在从SolrDocumentList中获取solr业务域中的字段,并取出service层封装的高亮,封装成List
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;
}
}
参数:queryString:查询条件
Page:页码
Rows:每页显示的记录数。
业务逻辑:
在e3-search-interface的SearchService创建接口
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;
}
在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;
}
}
dao层包扫描与发布service服务
配置包扫面的时候,可以扩大包扫描的范围
请求的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";
}
}
分页大小放入配置文件中
/e3-search-web/src/main/resources/conf/resource.properties
#搜索结果每页显示的记录数
SEARCH_RESULT_ROWS=60
还需要在springmvc.xml加载配置文件
发现无法翻页。
翻页处理:在e3-search-web工程中:修改如下:
修改url的端口,在这里可以看到前面说的page参数
5.6图片无法显示
这里说的是有图片的情况无法显示。
数据库中保存的图片是以逗号分隔的url列表,只需要展示第一张图片即可。
方法:
可以在SearchItem中添加一个getImages方法:
public String[] getImages() {
if(this.image != null&&!this.image.equals("")) {
String[] strings = this.image.split(",");
return strings;
}
return null;
}
原文:https://blog.csdn.net/pdsu161530247/article/details/81974760