首先写一个controller.即searchController.java
public class SearchController extendsAbstractCompassCommandController {
private String searchView;
private String searchResultsView;
private String searchResultsName ="searchResults";
private Integer pageSize;
private Integer sectionSize;
private CompassSearchHelper searchHelper;
publicCompassSearchHelper getSearchHelper() { return searchHelper;
}
public SearchController() { setCommandClass(CompassSearchCommand.class);
}
public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); if (searchView == null) { throw new IllegalArgumentException( "Must set the searchView property"); } if (searchResultsView == null) { throw new IllegalArgumentException( "Must set the serachResultsViewproperty"); } if (searchHelper == null) { searchHelper = new CompassSearchHelper(getCompass(),getPageSize()); } }
protected ModelAndView handle(HttpServletRequestrequest, HttpServletResponse response, Object command, BindExceptionerrors) throws Exception {
Log log4j =LogFactory.getLog("video"); log4j.info("SearchController say: hello");
final CompassSearchCommand searchCommand =(CompassSearchCommand) command;
String query = searchCommand.getQuery();
searchCommand.setQuery(query);
if (!StringUtils.hasText(searchCommand.getQuery())){ return new ModelAndView(getSearchView(), getCommandName(), searchCommand); }
CompassSearchResults searchResults =searchHelper.search(searchCommand);
log4j.info("searchResults.getHits().length= " + searchResults.getHits().length);
CompassPage page = newCompassPage(searchResults.getHits(), pageSize.intValue(), searchCommand.getPage().intValue() + 1, searchResults.getTotalHits(), sectionSize.intValue(), searchCommand.getQuery(), searchResults.getSearchTime());
return newModelAndView(getSearchResultsView(), "data", page);
}
/** * Returns the view that holds the screen which the user will initiatethe * search operation.
*/ public String getSearchView() { return searchView; }
/** * Sets the view that holds the screen which the user will initiate the * search operation. */ public void setSearchView(String searchView) { this.searchView = searchView; }
/** * Returns the name of the results that the * org.compass.core.support.search.CompassSearchResults}will be * saved under. Defaults to "searchResults". */ public String getSearchResultsName() { return searchResultsName; }
/** * Sets the name of the results that the * org.compass.core.support.search.CompassSearchResults}will be * saved under. Defaults to "searchResults". */
public void setSearchResultsName(StringsearchResultsName) { this.searchResultsName = searchResultsName; }
/** * Returns the view which will show the results of the search operation. */ public String getSearchResultsView() { return searchResultsView; }
/** * Sets the view which will show the results of the search operation. */ public void setSearchResultsView(String resultsView) { this.searchResultsView = resultsView; }
/** * Sets the page size for the pagination of the results. If not set, not * pagination will be used. */ public Integer getPageSize() { return pageSize; }
/** * Returns the page size for the pagination of the results. If not set,not * pagination will be used. * * @param pageSize * Thepage size when using paginated results */ public void setPageSize(Integer pageSize) { this.pageSize = pageSize; }
/** * <p> * The search helper is used to execute teh actual search. By default (if * not set) the search controller will create a new search helper. If * provided, the search controller will use it to perform the search. * * <p> * Mainly used to extend the search helper and execute additionaloperation * within specific calbacks the search helper exposes. * * @param searchHelper * Aspecific search helper to use */ public void setSearchHelper(CompassSearchHelper searchHelper) {
this.searchHelper = searchHelper; }
public Integer getSectionSize() { return sectionSize; }
public void setSectionSize(Integer sectionSize) { this.sectionSize = sectionSize; }}
还需要一个CompassPage.java主要来实现分页的。
public class CompassPage implements Page {
private CompassHit[] elements;
private int pageSize;
private int pageNumber;
private int totalElements = 0;
private int sectionSize;
private String query;
private long searchTime;
public long getSearchTime() { return searchTime; }
public void setSearchTime(long searchTime) { this.searchTime = searchTime;
}
/** * * @param pageNumber * 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码为最后一页编码。 * @param pageSize * 每一页显示的条目数 * @param sectionSize * 每一节显示的页数. */ public CompassPage(CompassHit[] elements, int pageSize, int pageNumber,int totalElements, int sectionSize, String query, long searchTime) { super(); this.elements = elements; this.pageSize = pageSize; this.pageNumber = pageNumber; this.totalElements = totalElements; this.sectionSize = sectionSize; this.query = query; this.searchTime = searchTime;
if (Integer.MAX_VALUE == this.pageNumber || this.pageNumber > getLastPageNumber()) // lastpage { this.pageNumber = getLastPageNumber(); } }
public String getQuery() { return query; }
public void setQuery(String query) { this.query = query; }
public CompassHit[] getElements() { return elements; }
public void setElements(CompassHit[] elements) { this.elements = elements; }
public int getPageNumber() { return pageNumber; }
public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; }
public int getSectionSize() { return sectionSize; }
public void setSectionSize(int sectionSize) { this.sectionSize = sectionSize; }
public int getTotalElements()
return totalElements; }
public void setTotalElements(int totalElements) { this.totalElements = totalElements; }
public void setPageSize(int pageSize) { this.pageSize = pageSize; }
public int getLastPageNumber() { return totalElements % this.pageSize == 0 ? totalElements / this.pageSize : totalElements / this.pageSize + 1; }
public int getNextPageNumber() { return getThisPageNumber() + 1; }
public int getNextSectionFirstPageNumber() { return (pageNumber / sectionSize + 1) * sectionSize + 1; }
public int getPageSize() { return pageSize; }
public int getPreviousPageNumber() { return (getThisPageNumber() == 1) ? 1 : getThisPageNumber() - 1; }
public int getPreviousSectionFirstPageNumber() { return (pageNumber / sectionSize - 1) * sectionSize + 1; }
public Object getThisPageElements() { return elements; }
public int getThisPageFirstElementNumber() { return (getThisPageNumber() - 1) * getPageSize() + 1; }
public int getThisPageLastElementNumber() { int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1; return getTotalNumberOfElements() < fullPage ?getTotalNumberOfElements() : fullPage; }
publicint getThisPageNumber() { return pageNumber;
}
public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; }
public int getThisSectionFirstPageNumber() { return (getThisPageNumber() % sectionSize == 0) ?getThisPageNumber() / sectionSize * sectionSize : getThisPageNumber() /sectionSize * sectionSize + 1; }
publicint getThisSectionLastPageNumber() { int fullSection = (getThisPageNumber() / sectionSize + 1) *sectionSize; return getLastPageNumber() < fullSection ? getLastPageNumber() : fullSection;
public List getThisSectionPagesBar() { // 翻页 页码条 List pagesBar = new ArrayList();
if(hasPreviousSection()) { // 不是第一捆 if (hasNextSection()) {// 不是最后一捆 for (int j = getPreviousSectionFirstPageNumber() +sectionSize; j <= getNextSectionFirstPageNumber() - 1; j++) { pagesBar.add(new Integer(j)); } } else { // 是最后一捆 for (int j = getPreviousSectionFirstPageNumber() +sectionSize; j <= (getLastPageNumber()); j++) {
pagesBar.add(new Integer(j)); } } } else { // 是第一捆 // log4j.info("是第一捆getLastPageNumber()=" + getLastPageNumber());
for(int j = 1; j <= (getLastPageNumber() < sectionSize ? getLastPageNumber() : sectionSize); j++) { // log4j.info("j=" + j);
pagesBar.add(new Integer(j)); } } return pagesBar; }
public int getTotalNumberOfElements() { return totalElements; }
public boolean hasNextPage() { return getLastPageNumber() > getThisPageNumber(); }
public boolean hasNextSection() { return getLastPageNumber() > (pageNumber / sectionSize + 1) * sectionSize; }
publicboolean hasPreviousPage() { return getThisPageNumber() > 1;
}
public boolean hasPreviousSection() { return pageNumber / sectionSize * sectionSize > 1; }
public boolean isFirstPage() { return getThisPageNumber() == 1; }
public boolean isLastPage() { return getThisPageNumber() >= getLastPageNumber(); }
}在定义一个分页接口Page.java。
/** * 分页信息接口 */public interface Page{ /** * 是否是首页(第一页),第一页页码为1 * * @return 首页标识 */ public boolean isFirstPage();
/** * 是否是最后一页 * * @return 末页标识 */ public boolean isLastPage();
/** * 是否有下一页 * * @return 下一页标识 */ public boolean hasNextPage();
/** * 是否有上一页 * * @return 上一页标识 */ public boolean hasPreviousPage();
/** 是否有下一个页面单元 */ public boolean hasNextSection();
/**是否有前一个页面单元*/
public boolean hasPreviousSection();
/** * 获取最后一页页码,也就是总页数 * * @return 最后一页页码 */ public int getLastPageNumber();
/** * 当前页包含的数据,不同的情况可能返回的数据类型不一样,如List,RowSet等,请参考具体的实现 * * @return 当前页数据源 */ public Object getThisPageElements();
/** * 总的数据条目数量,0表示没有数据 * * @return 总数量 */ public int getTotalNumberOfElements();
/** * 获取当前页的首条数据的行编码 * * @return 当前页的首条数据的行编码 */ public int getThisPageFirstElementNumber();
/** * 获取当前页的末条数据的行编码 * * @return 当前页的末条数据的行编码 */ public int getThisPageLastElementNumber();
/** * 获取下一页编码 *
* @return 下一页编码 */ public int getNextPageNumber();
/** * 获取上一页编码 * * @return 上一页编码 */ public int getPreviousPageNumber();
/* 获取下一个页面单元的第一页 */ public int getNextSectionFirstPageNumber();
/* 获取前一个页面单元的第一页 */ public int getPreviousSectionFirstPageNumber();
/** * 每一页显示的条目数 * * @return 每一页显示的条目数 */ public int getPageSize();
/** * 当前页的页码 * * @return 当前页的页码 */ public int getThisPageNumber();
/* 当前片断第一页页码 */ public int getThisSectionFirstPageNumber();
/* 当前片断第一页页码 */ public int getThisSectionLastPageNumber();
/* *当前片断 页码表 */ public List getThisSectionPagesBar();
}
最后要配置一下bean和请求映射了。
<bean id="urlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <propkey="/search.htm">searchController</prop> </props> </property> </bean>
<!-- 搜索的控制器 --> <bean id="searchController" class="com.jack.video.SearchController"lazy-init="true"> <property name="compass" ref="compass" /> <property name="searchView"value="/ftl/search.ftl" /> <property name="searchResultsView" value="/ftl/search.ftl" /> <property name="pageSize" value="10" /> <property name="sectionSize" value="10"/> <property name="searchHelper"> <ref local="advanceCompassSearchHelper" /> </property> </bean>
最后为了能给搜索到的结果高亮显示。还需要配置。
<!--高亮字段显示 --> <bean id="advanceCompassSearchHelper" class="com.jack.video.util.AdvanceCompassSearchHelper"> <property name="highlightFields"> <list> <value>CName</value> </list>
</property> <property name="pageSize"> <value>10</value> </property> <constructor-arg ref="compass" /> </bean>
AdvanceCompassSearchHelper .java文件
public class AdvanceCompassSearchHelper extendsCompassSearchHelper { private String[] highlightFields;
public String[] getHighlightFields() { return highlightFields; }
public void setHighlightFields(String[]highlightFields) { this.highlightFields = highlightFields; }
/** * @param compass */ public AdvanceCompassSearchHelper(Compass compass) { super(compass); }
/* * (non-Javadoc) * * @see org.compass.core.support.search.CompassSearchHelper#doProcessBeforeDetach(org.compass.core.support.search.CompassSearchCommand, * org.compass.core.CompassSession,org.compass.core.CompassHits, int, * int)
*/ @Override protected void doProcessBeforeDetach(CompassSearchCommand searchCommand, CompassSession session, CompassHits hits, int from, int size){ if (from < 0) { from = 0; size = hits.getLength(); } if (highlightFields == null) { return; } // highlight fields for (int i = from; i < size; i++) { for (String highlightField : highlightFields) { hits.highlighter(i).fragment(highlightField); } } }}最后就剩下简单的搜索页面和显示页面了。
这是搜索页主要的代码。
<form method="get"action="/search.htm"> <inputtype="text" size="50" name="query" value="${query?if_exists}"/> <inputtype="hidden" name="page" value="1"/>
<inputtype="submit" value="搜索" /></form>
以下是结果页的主要代码。
<#macro s_search_result data=""config=""> <script type="text/javascript"> var videoList = { channelId: ${channelId}
}; </script> <div> <div> <divclass="title"> <@s_option_button /> <ul> <li><ahref="javascript:;"><span>搜索结果</span></a></li>
</ul> </div> <divclass="content"> <@s_module_config data=config /> <div> </div> <div> <ul> <li>共有 ${data.totalElements} 项符合 ${data.query} 的查询结果</li> <li>第 ${data.pageNumber}/${data.lastPageNumber} 页</li> <li>用时 ${data.searchTime} 毫秒</li> </ul> <ul> <li></li> <li></li> </ul> </div> <#if data.elements?exists && data.elements?has_content > <#list data.elements as d> <div> <div> <div> <p> <strong>名字:</strong><@s_sev=d.data.description /> </p> <p> <strong>导演:</strong> <span><@s_se v=d.data.director/></span> </p> <p> <strong>类型:</strong> <span><@s_se v=d.data.genre/></span> </p> </div> </div> </div> </div> </#list> <ul> <li> <span>共有<b>${data.totalElements}</b> 项 第 <b>${data.pageNumber}</b> /<b>${data.lastPageNumber}</b> 页</span> </li> <li> <ahref="/search.htm?query=${data.query}&page=1" title="第一页">←</a> </li> <#if(data.getThisSectionFirstPageNumber()>1)> <li> <ahref="/search.htm?query=${data.query}&page=${data.getThisSectionFirstPageNumber()}"title="快速向前翻10页"/><<</a> </li> </#if> <#if (data.getPreviousPageNumber()>1)> <li> <ahref="/search.htm?query=${data.query}&page=${data.getPreviousPageNumber()}"title="向前翻1页"/><</a> </li> </#if> <#if data.getThisSectionPagesBar()?exists> <#list data.getThisSectionPagesBar() asd> <li> <ahref="/search.htm?query=${data.query}&page=${d}">${d}</a> </li> </#list> </#if> <#if (data.getNextPageNumber()<=data.lastPageNumber)> <li> <ahref="/search.htm?query=${data.query}&page=${data.getNextPageNumber()}"title="向后翻1页"/>></a> </li> </#if> <#if(data.getNextSectionFirstPageNumber()<=data.lastPageNumber)> <li> <ahref="/search.htm?query=${data.query}&page=${data.getNextSectionFirstPageNumber()}"title="快速向后翻10页"/>>></a> </li> </#if> <li> <ahref="/search.htm?query=${data.query}&page=${data.lastPageNumber}"title="最后一页">→</a> </li> </ul> <#else> 暂无相关影片 </#if> </div> </div> </div></#macro>
现在把快速给你的网站搭建搜索功能已讲完。写的过程中可能有不对的地方,希望你在调试的时候该过来。
基本的实现原理及过程已讲了,至于如何用,就看你自己来。
我主要快速的把要点讲了一下。里面还有很多细节。有时间的话再和大家讨论。
value="${query?if_exists}" /> <input type="hidden" name="page" value="1"/> <input type="submit" value="搜索"
展开