solr进阶七:与jQuery结合的自动补全功能

来源:互联网 发布:淘宝卖家怎么催快递 编辑:程序博客网 时间:2024/06/07 12:42

网上有大量的jQuery自动补全功能的插件,我实现这个功能是采用网友写好的纯jQuery代码,而不是采用插件,因为特效会差很多。而后台的数据是从solr那边获取过来,通过整理,放到对象中,再放到集合中,然后在servlet层解开,生成xml文件,返回到前台,形成自动提示补全的功能,流程非常简单,没有采用框架技术,只是用了JSPservlet来做中间层而已。


目录结构如下:


1.先编写实体类src\com\lifeix\entity\Word.java

[java] view plain copy
  1. package com.lifeix.entity;  
  2.   
  3. /** 
  4.  * Created by lhx on 14-12-9 上午9:38 
  5.  * 
  6.  * @project jspProject 
  7.  * @package com.lifeix.entity 
  8.  * @blog http://blog.csdn.net/u011439289 
  9.  * @email 888xin@sina.com 
  10.  * @Description 
  11.  */  
  12. public class Word {  
  13.     //次数  
  14.     private int number ;  
  15.     //名称  
  16.     private String name ;  
  17.   
  18.     public Word(){}  
  19.   
  20.     public Word(int number, String name){  
  21.         this.number = number ;  
  22.         this.name = name ;  
  23.     }  
  24.   
  25.     public int getNumber() {  
  26.         return number;  
  27.     }  
  28.   
  29.     public void setNumber(int number) {  
  30.         this.number = number;  
  31.     }  
  32.   
  33.     public String getName() {  
  34.         return name;  
  35.     }  
  36.   
  37.     public void setName(String name) {  
  38.         this.name = name;  
  39.     }  
  40. }  

2.编写一个servlet测试一下src\com\lifeix\servlet\AutoCompleteServlet.java

[java] view plain copy
  1. package com.lifeix.servlet;  
  2.   
  3. import com.lifeix.entity.Word;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9. import java.io.IOException;  
  10. import java.io.PrintWriter;  
  11. import java.util.ArrayList;  
  12. import java.util.Iterator;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Created by lhx on 14-12-9 上午9:31 
  17.  * 
  18.  * @project jspProject 
  19.  * @package ${PACKAGE_NAME} 
  20.  * @blog http://blog.csdn.net/u011439289 
  21.  * @email 888xin@sina.com 
  22.  * @Description 
  23.  */  
  24. public class AutoCompleteServlet extends HttpServlet {  
  25.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  26.   
  27.         StringBuffer sf = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");  
  28.         sf.append("<message>");  
  29.   
  30.         List<Word> list = new ArrayList<Word>(10);  
  31.         Word word = null ;  
  32.         for (int i = 0; i < 10; i++) {  
  33.             word = new Word(i, "abd" + i);  
  34.             list.add(word);  
  35.         }  
  36.   
  37.         Iterator<Word> it = list.iterator();  
  38.         while (it.hasNext()){  
  39.             Word word1 = it.next();  
  40.             if (word1 == null){  
  41.                 continue;  
  42.             }  
  43.             int number = word1.getNumber();  
  44.             String name = word1.getName();  
  45.             sf.append("<word>"+name);  
  46.             sf.append("</word>");  
  47.         }  
  48.         sf.append("</message>");  
  49.         PrintWriter pw = null;  
  50.         try {  
  51.             response.setContentType("text/xml;charset=utf-8");  
  52.             response.setCharacterEncoding("UTF-8");  
  53.             response.setHeader("Cache-Control""no-cache");  
  54.             pw = response.getWriter();  
  55.             pw.print(sf.toString());  
  56.             pw.flush();  
  57.         }catch (Exception e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.         finally {  
  61.             if (pw != null)  
  62.                 pw.close();  
  63.         }  
  64.     }  
  65.   
  66.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  67.         this.doPost(request,response);  
  68.     }  
  69. }  

启动tomcat,访问这个servlet,结果如下:


证明返回的确实是XML文档。

 

3.直接编写页面文档jspProject\web\auto2.html

[html] view plain copy
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  
  2.         "http://www.w3.org/TR/html4/loose.dtd">  
  3. <html>  
  4. <head>  
  5.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  6.     <title>jQuery 自动完成功能(优化版)</title>  
  7.     <script type="text/javascript" src="js/jquery-2.1.1.js"></script>  
  8. </head>  
  9. <body>  
  10. <script type="text/javascript">  
  11.     var highlightindex = -1;//表示当前高亮节点  
  12.     var timeoutId;  
  13.     $(document).ready(function() {  
  14.         var wordInput = $("#word");//文本框  
  15.         var wordInputOffset = wordInput.offset();//获得文本框位置  
  16.         $("#auto").hide().css("border", "1px black solid").css("position", "absolute")  
  17.                 .css("top", wordInputOffset.top + wordInput.height() + 5 + "px")  
  18.                 .css("left", wordInputOffset.left + "px").width(wordInput.width() + 3 + "px");  
  19.         wordInput.keyup(function(event) {  
  20.                     //处理文本框中的键盘事件  
  21.                     //如果输入字母,将文本框中最新信息发送给服务器  
  22.                     var myEvent = event || window.event;  
  23.                     var keyCode = myEvent.keyCode;//获得键值  
  24.   
  25.                     if (keyCode == 27) {  
  26.                         var wordText = $("#word").val();  
  27.                         autoHide();  
  28.                         wordInput.text(wordText);  
  29.                     }  
  30.                     else {  
  31.                         if (keyCode >= 65 && keyCode <= 90 || keyCode == 8 || keyCode == 46) { //8对应退格键,46对应删除键  
  32.                             var wordText = $("#word").val();//获得文本框中的内容  
  33.                             var autoNode = $("#auto");  
  34.                             if (wordText != "") {  
  35.                                 clearTimeout(timeoutId);//对上次未完成的延时操作进行取消  
  36.                                 //延时操作,减少与服务器的交互次数,延时500ms,防止用户操作过快  
  37.                                 timeoutId = setTimeout(function() {  
  38.                                     $.post("AutoCompleteServlet", {word:wordText}, function(data) {//发送数据,第二项是属性名对应属性值  
  39.                                         var jqueryObj = $(data);//将dom对象data转换成jQuery的对象  
  40.                                         var wordNodes = jqueryObj.find("word");//找到所有word节点  
  41.                                         autoNode.html("");  
  42.                                         wordNodes.each(function(i) { //i是索引,用来给id赋值  
  43.                                             var wordNode = $(this);//获取单词内容  
  44.                                             var newDivNode = $("<div>").attr("id", i).css("backgroundColor", "white");  
  45.                                             newDivNode.html(wordNode.text()).appendTo(autoNode);//新建div节点,加入单词内容  
  46.                                             //增加鼠标进入事件,高亮节点  
  47.                                             newDivNode.mouseover(function() {  
  48.                                                 //将原来高亮的节点取消高亮  
  49.                                                 if (highlightindex != -1) {  
  50.                                                     $("#auto").children("div").eq(highlightindex)  
  51.                                                             .css("backgroundColor", "white");  
  52.                                                 }  
  53.                                                 //记录新的高亮索引  
  54.                                                 highlightindex = $(this).attr("id");  
  55.                                                 $(this).css("backgroundColor", "#3366CC").css("cursor","pointer");  
  56.                                             });  
  57.                                             //增加鼠标移出事件,取消节点高亮  
  58.                                             newDivNode.mouseout(function() {  
  59.                                                         if (keyCode == 13) {       //判断是否按下回车键  
  60.                                                             //下拉框有高亮  
  61.                                                             if (highlightindex != -1) {  
  62.                                                                 lightEventHide();  
  63.                                                                 highlightindex = -1;  
  64.                                                             } else {  
  65.                                                                 alert("文本框中的[" + $("#word").val() + "]被提交了");  
  66.                                                                 autoHide();  
  67.                                                                 $("#word").get(0).blur();//让文本框失去焦点  
  68.                                                             }  
  69.                                                             //取消鼠标移出节点的高亮  
  70.                                                             //$(this).css("backgroundColor", "white");  
  71.                                                         }  
  72.                                                     }  
  73.                                             );  
  74.                                             //增加鼠标点击事件,可以进行补全  
  75.                                             newDivNode.click(function() {  
  76.                                                 //取出高亮节点的文本内容  
  77.                                                 var comText = $(this).text();  
  78.                                                 autoHide();  
  79.                                                 highlightindex = -1;  
  80.                                                 //文本框内容变为高亮节点内容  
  81.                                                 $("#word").val(comText);  
  82.                                             });  
  83.                                         });  
  84.                                         //添加单词内容到弹出框  
  85.                                         if (wordNodes.length > 0) {  
  86.                                             autoNode.show();  
  87.                                         } else {  
  88.                                             autoNode.hide();  
  89.                                             highlightindex = -1;//弹出框隐藏,高亮节点索引设成-1  
  90.                                         }  
  91.                                     }, "xml");  
  92.                                 }, 300);  
  93.                             }  
  94.                             else  
  95.                             {  
  96.                                 autoNode.hide();  
  97.                                 highlightindex = -1;  
  98.                             }  
  99.                         } else if (keyCode == 38 || keyCode == 40) {   //判断是否输入的是向上38向下40按键  
  100.                             if (keyCode == 38) {  
  101.                                 var autoNodes = $("#auto").children("div").css("background-color", "white");  
  102.                                 if (highlightindex != -1) {  
  103.                                     autoNodes.eq(highlightindex).css("background-color", "white");  
  104.                                     highlightindex--;  
  105.                                 } else {  
  106.                                     lightEvent();  
  107.                                     highlightindex = autoNodes.length - 1;  
  108.                                 }  
  109.                                 if (highlightindex == -1) {  
  110.                                     highlightindex = autoNodes.length - 1;//如果改变索引值后index变成-1,则将索引值指向最后一个元素  
  111.                                 }  
  112.                                 lightEvent();  
  113.                                 autoNodes.eq(highlightindex).css("backgroundColor", "#3366CC");  
  114.                             }  
  115.                             if (keyCode == 40) {  
  116.                                 var autoNodes = $("#auto").children("div");  
  117.                                 if (highlightindex != -1) {  
  118.                                     autoNodes.eq(highlightindex).css("background-color", "white");  
  119.                                 }  
  120.                                 highlightindex++;  
  121.                                 if (highlightindex == autoNodes.length) {  
  122.                                     highlightindex = 0;//如果改变索引值等于最大长度,则将索引值指向第一个元素  
  123.   
  124.                                 }  
  125.                                 lightEvent();  
  126.                                 autoNodes.eq(highlightindex).css("backgroundColor", "#3366CC");  
  127.                             }  
  128.                         } else if (keyCode == 13) {       //判断是否按下回车键  
  129.                             //下拉框有高亮  
  130.                             if (highlightindex != -1) {  
  131.                                 lightEventHide();  
  132.                                 highlightindex = -1;  
  133.                             } else {  
  134.                                 alert("文本框中的[" + $("#word").val() + "]被提交了");  
  135.                                 $("#auto").hide();  
  136.                                 $("#word").get(0).blur();//让文本框失去焦点  
  137.                             }  
  138.                             //下拉框没有高亮  
  139.                         }  
  140.                     }  
  141.                 }  
  142.         )  
  143.         ;  
  144.         $("input[type='button']").click(function() {  
  145.             alert("文本框中的[" + $("#word").val() + "]被提交了");  
  146.         });  
  147.     });  
  148.     function lightEventHide(){  
  149.         var comText = $("#auto").hide().children("div").eq(highlightindex).text();  
  150.         $("#word").val(comText);  
  151.     }  
  152.     function lightEvent(){  
  153.         var comText = $("#auto").children("div").eq(highlightindex).text();  
  154.         $("#word").val(comText);  
  155.     }  
  156.     function autoHide(){  
  157.         $("#auto").hide();  
  158.     }  
  159. </script>  
  160.   
  161. <h3>  
  162.     <center>仿google自动补全(jQuery优化版)</center>  
  163. </h3>  
  164. <br />  
  165. <table align="center">  
  166.     <tr><td>  
  167.         <input type="text" id="word" maxlength=2048 size=55 />  
  168.         <br/>  
  169.         <td></tr>  
  170.     <tr><td align="center">  
  171.         <input type="button" value="shiyang 搜索"/>  
  172.     </td></tr>  
  173. </table>  
  174. <br />  
  175. <div id="auto"></div>  
  176. </body>  
  177. </html>  

这个例子引用:施杨de编程世界www.cnblogs.com/shiyangxt

 

4.重启tomcat,打开这个页面,访问:


不管是首字母还是中间的,都会有提示了!

这个demo没有和solr结合,现在我们加入solr,直接从solr里面取数据!

访问solr管理页面,选择要搜索的core和字段,还有值,看看有没有搜索结果出来。后期会加入可以动态编辑的字段还有值,使例子更实用些。


1.编写后台类,与solr交互,获取数据src\com\lifeix\util\SolrGetFtTopic.java

[java] view plain copy
  1. package com.lifeix.util;  
  2.   
  3. import com.lifeix.entity.Word;  
  4. import org.apache.solr.client.solrj.SolrServer;  
  5. import org.apache.solr.client.solrj.SolrServerException;  
  6. import org.apache.solr.client.solrj.impl.HttpSolrServer;  
  7. import org.apache.solr.client.solrj.response.QueryResponse;  
  8. import org.apache.solr.common.SolrDocument;  
  9. import org.apache.solr.common.SolrDocumentList;  
  10. import org.apache.solr.common.params.ModifiableSolrParams;  
  11.   
  12. import java.util.ArrayList;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Created by lhx on 14-12-9 上午10:30 
  17.  * 
  18.  * @project jspProject 
  19.  * @package com.lifeix.util 
  20.  * @blog http://blog.csdn.net/u011439289 
  21.  * @email 888xin@sina.com 
  22.  * @Description 
  23.  */  
  24. public class SolrGetFtTopic {  
  25.     private static final String SOLR_URL = "http://192.168.199.22:8080/xxx/";  
  26.   
  27.     public List<Word> queryAll(){  
  28.         ModifiableSolrParams params = new ModifiableSolrParams();  
  29.         params.set("q","topicName:次");  
  30.         params.set("start",0);  
  31.         params.set("rows",Integer.MAX_VALUE);  
  32.   
  33.         params.set("sort","score desc");  
  34.         params.set("f1","*,score");  
  35.   
  36.         SolrServer server = new HttpSolrServer(SOLR_URL);  
  37.   
  38.         List<Word> listWord = new ArrayList<Word>() ;  
  39.         Word word = null ;  
  40.   
  41.         try {  
  42.             QueryResponse response = server.query(params);  
  43.             SolrDocumentList list = response.getResults();  
  44.             for (int i = 0; i < list.size(); i++) {  
  45.                 word = new Word();  
  46.                 SolrDocument document = list.get(i);  
  47.                 word.setName( (String)document.getFieldValue("topicName") );  
  48.                 listWord.add(word);  
  49.             }  
  50.             return  listWord ;  
  51.         } catch (SolrServerException e) {  
  52.             e.printStackTrace();  
  53.         }  
  54.         return null ;  
  55.     }  
  56. }  

2.修改src\com\lifeix\servlet\AutoCompleteServlet.java,主要就是把静态数据换成了从solr后台获取的list集合数据

[java] view plain copy
  1. package com.lifeix.servlet;  
  2.   
  3. import com.lifeix.entity.Word;  
  4. import com.lifeix.util.SolrGetFtTopic;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import java.io.IOException;  
  11. import java.io.PrintWriter;  
  12. import java.util.Iterator;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Created by lhx on 14-12-9 上午9:31 
  17.  * 
  18.  * @project jspProject 
  19.  * @package ${PACKAGE_NAME} 
  20.  * @blog http://blog.csdn.net/u011439289 
  21.  * @email 888xin@sina.com 
  22.  * @Description 
  23.  */  
  24. public class AutoCompleteServlet extends HttpServlet {  
  25.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  26.   
  27.         StringBuffer sf = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");  
  28.         sf.append("<message>");  
  29.         SolrGetFtTopic solrGetFtTopic = new SolrGetFtTopic();  
  30.         List<Word> list = solrGetFtTopic.queryAll();  
  31.         Iterator<Word> it = list.iterator();  
  32.         while (it.hasNext()){  
  33.             Word word1 = it.next();  
  34.             if (word1 == null){  
  35.                 continue;  
  36.             }  
  37.             String name = word1.getName();  
  38.             sf.append("<word>"+name);  
  39.             sf.append("</word>");  
  40.         }  
  41.         sf.append("</message>");  
  42.         PrintWriter pw = null;  
  43.         try {  
  44.             response.setContentType("text/xml;charset=utf-8");  
  45.             response.setCharacterEncoding("UTF-8");  
  46.             response.setHeader("Cache-Control""no-cache");  
  47.             pw = response.getWriter();  
  48.             pw.print(sf.toString());  
  49.             pw.flush();  
  50.         }catch (Exception e) {  
  51.             e.printStackTrace();  
  52.         }  
  53.         finally {  
  54.             if (pw != null)  
  55.                 pw.close();  
  56.         }  
  57.     }  
  58.   
  59.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  60.         this.doPost(request,response);  
  61.     }  
  62. }  

3.前台页面的jQuery代码可以纹丝不动,重启tomcat,先访问servlet,看看数据能不能正常获取:

没问题!!访问页面,也一样没问题!