首先写一个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> 项&nbsp;第 <b>${data.pageNumber}</b> /<b>${data.lastPageNumber}</b> 页</span>
     </li>
     <li>
      <ahref="/search.htm?query=${data.query}&page=1" title="第一页">&larr;</a>
     </li>
     <#if(data.getThisSectionFirstPageNumber()>1)>
      <li>
       <ahref="/search.htm?query=${data.query}&page=${data.getThisSectionFirstPageNumber()}"title="快速向前翻10页"/>&lt;&lt;</a>
      </li>
     </#if>
     <#if (data.getPreviousPageNumber()>1)>
      <li>
       <ahref="/search.htm?query=${data.query}&page=${data.getPreviousPageNumber()}"title="向前翻1页"/>&lt;</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页"/>&gt;</a>
      </li>
     </#if>
     <#if(data.getNextSectionFirstPageNumber()<=data.lastPageNumber)>
      <li>
       <ahref="/search.htm?query=${data.query}&page=${data.getNextSectionFirstPageNumber()}"title="快速向后翻10页"/>&gt;&gt;</a>
      </li>
     </#if>
     <li>
      <ahref="/search.htm?query=${data.query}&page=${data.lastPageNumber}"title="最后一页">&rarr;</a>
     </li>
    </ul>
             <#else>
                 暂无相关影片
             </#if>
            </div>
        </div>
    </div>
</#macro>

   现在把快速给你的网站搭建搜索功能已讲完。写的过程中可能有不对的地方,希望你在调试的时候该过来。

基本的实现原理及过程已讲了,至于如何用,就看你自己来。

我主要快速的把要点讲了一下。里面还有很多细节。有时间的话再和大家讨论。

 

 

 

          

  • value="${query?if_exists}"     /&gt; &lt;input type="hidden" name="page"     value="1"/&gt; &lt;input type="submit"     value="搜索"

展开