首页 > 代码库 > Servlet+Ajax实现搜索智能提示

Servlet+Ajax实现搜索智能提示

一般在百度搜索框输入关键词时,会弹出一些相关信息提示,方便点选:

技术分享

页面(search.jsp):

技术分享
1 <input type="text"  name="keyWords" id="keyWords"  style="width:200px; height:20px;"  /> 
2 <input type="button" id="button" value="百度一下">
HTML

创建新的div层,用以放置获取到的提示内容:

技术分享
 1     <div>
 2         <input type="text"  name="keyWords" id="keyWords" style="width:200px; height:20px;" /> 
 3                 <input type="button" id="button" value="百度一下">
 4             <div id="popDiv">
 5             <table id="content_table">
 6                 <tbody id="content_table_body">
 7                 </tbody>
 8             </table>
 9         </div>
10     </div>
HTML

创建XMLHttpRequest对象:

技术分享
 1     function createXmlHttp()
 2     {
 3         var xmlHttp;
 4         //创建XMLHttpRequest
 5         if(window.XMLHttpRequest)
 6             {
 7             xmlHttp = new XMLHttpRequest();
 8             //兼容某些Mozilla浏览器的响应头,强制设置为text/xml,具体参看:http://www.cnblogs.com/perseverancevictory/p/3690769.html
 9                if(xmlHttp.overrideMimeType){  
10                    xmlHttp.overrideMimeType("text/xml");  
11                }
12             }
13         //兼容IE
14         else if(window.ActiveXObject)
15             {
16             xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
17             if(!xmlHttp)
18                 {
19                 xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
20                 }
21             }
22         return xmlHttp;
23     }
javascript

当输入时出现提示,因此需要在input框中添加onkeyup事件,用以获取相关提示:

技术分享
1 <input type="text"  name="keyWords" id="keyWords"  style="width:200px; height:20px;" onkeyup="getMoreContens()" />
HTML

实现onkeyup事件:

技术分享
 1         var xmlHttp;
 2     //获取用户输入的关联信息的函数
 3     function getMoreContens() {
 4         //获取用户输入
 5         var content = document.getElementById("keyWords").value;
 6         if (content == "") {
 7             clearContent();
 8             return;
 9         }
10         xmlHttp = createXmlHttp();
11         //给服务器发送数据
12         var url = "search?keyword="+encodeURI(content); 
13         xmlHttp.open("GET",url,true);
14         xmlHttp.onreadystatechange =     //回调函数
15             function callback()
16         {
17             if(xmlHttp.readyState == 4)
18                 {
19                 if(xmlHttp.status == 200){
20                     var result = decodeURIComponent(xmlHttp.responseText);
21                     var json = eval("("+result+")");
22                     clearContent(json);
23                     intelliSense(json);
24                 }
25                 }
26         };
27         /*
28             xmlhttp的send是传递参数用的,但是只有在使用post方式提交请求的时候才有用
29             如下:
30             xmlhttp.open("post",url,true); 
31             ...
32             xmlhttp.send("data=http://www.mamicode.com/data&data2=data2");
33              
34             用get的话一般就是:
35             xmlhttp.open("get",url,true); 
36             ...
37             xmlhttp.send(null);
38         */
39         xmlHttp.send(null);
40     }
javascript

可以看到,getMoreConten()方法中有clearContent()和intelliSense(json)两个自定义方法,它们的作用分别是清空提示和根据输入智能获取关键字,实现如下:

intelliSense(获取智能提示并放置在输入框下方table中):

技术分享
 1     function intelliSense(json)
 2     {
 3         //获取关联数据的长度
 4         var size = json.length;
 5         for(var i=0;i<size;i++)
 6             {
 7             var nextNode = json[i];
 8             var tr= document.createElement("tr");
 9             var td= document.createElement("td");
10             tr.setAttribute("border", "0");
11             tr.setAttribute("bgcolor", "#EDEDED");
12             td.setAttribute("width", "200px");
13             td.onmouseover=function()
14             {
15                 this.className = ‘mouseOver‘;
16             }
17             td.onmouseout=function()
18             {
19                 this.className = ‘mouseOut‘;
20             }
21             td.onclick=function()
22             {
23                 document.getElementById("keyWords").value=http://www.mamicode.com/this.innerText;
24             }
25             var text=document.createTextNode(nextNode);
26             td.appendChild(text);
27             tr.appendChild(td);
28             document.getElementById("content_table_body").appendChild(tr);
29             }
30     }
javascript

clearContent:

技术分享
1     function clearContent()
2     {
3         var contentTableBody = document.getElementById("content_table_body");
4         var size = contentTableBody.childNodes.length;
5         for(var i=size-1;i>0;i--)
6             {
7             contentTableBody.removeChild(contentTableBody.childNodes[i]);
8             }
9     }
javascript

页面上基本完成,接下来需要实现getMoreContens方法中定义的名叫search的Servlet:

在web.xml中配置:

技术分享
1 <servlet-mapping>
2     <servlet-name>search</servlet-name>
3     <url-pattern>/search</url-pattern>
4 </servlet-mapping>
5 <servlet>
6     <description>搜索</description>
7     <servlet-name>search</servlet-name>
8     <servlet-class>com.yan.search.SearchServlet</servlet-class>
9 </servlet> 
xml

Servlet实现:

技术分享
 1 private static List<String> keyWordList = new ArrayList<String>();
 2     static {
 3         // 模拟数据
 4         keyWordList.add("yanwei");
 5         keyWordList.add("yantian");
 6         keyWordList.add("yanpeng");
 7         keyWordList.add("yanweichao");
 8         keyWordList.add("yanweiqi");
 9         keyWordList.add("yanyurong");
10         keyWordList.add("yanmeirong");
11         keyWordList.add("yanweichen");
12         keyWordList.add("电影");
13         keyWordList.add("电影 66ys");
14     }
15     private static final long serialVersionUID = 1L;
16 
17     @Override
18     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
19             throws ServletException, IOException {
20         doGet(req, resp);
21     }
22 
23     @Override
24     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
25             throws ServletException, IOException {
26 
27         String keyWord = req.getParameter("keyword");
28         System.out.println(keyWord);
29         List<String> list = keyWord==null?new ArrayList<String>():getDatas(keyWord);
30         String json = JSON.toJSONString(list);
31         //防止乱码
32         String encodeJSON = URLEncoder.encode(json,"UTF-8");
33         resp.getWriter().write(encodeJSON);
34     }
35 
36     public static List<String> getDatas(String keyWord) {
37         List<String> list = new ArrayList<String>();
38         for (int i = 0; i < keyWordList.size(); i++) {
39             if (keyWordList.get(i).contains(keyWord)) {
40                 list.add(keyWordList.get(i));
41             }
42         }
43         return list;
44     }
Java

此时基本功能已经实现,但还有一些小细节需要处理:

1.当文本框失去焦点时,提示应该消失

在输入框属性中添加onblur事件,触发clearContent方法;

2.获得焦点时再次出现提示

在输入框属性中添加onfocus事件,触发intelliSense方法;

3.当鼠标滑过载有提示信息的table时,应加一些样式显得更友好:

我们在intelliSense方法中已经为td元素设置了类名mouseOver和mouseOut,因此添加css样式即可:

技术分享
1 .mouseOver {
2     background: #00B2EE;
3     color: white;
4     width: 200px;
5 }
6 .mouseOut {
7     background: #EDEDED;
8     width: 200px;
9 }
CSS

呈现效果:

技术分享

最终代码:

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 3 <welcome-file-list>
 4     <welcome-file>index.jsp</welcome-file>
 5 </welcome-file-list>
 6 <servlet-mapping>
 7     <servlet-name>search</servlet-name>
 8     <url-pattern>/search</url-pattern>
 9 </servlet-mapping>
10 <servlet>
11     <description>搜索</description>
12     <servlet-name>search</servlet-name>
13     <servlet-class>com.yan.search.SearchServlet</servlet-class>
14 </servlet> 
15 </web-app>
web.xml

 

技术分享
  1 <%@ page language="java" contentType="text/html; charset=UTF-8"
  2     pageEncoding="UTF-8"%>
  3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4 <html>
  5 <head>
  6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7 <title>smart search</title>
  8 <style type="text/css">
  9 .mouseOver {
 10     background: #00B2EE;
 11     color: white;
 12     width: 200px;
 13 }
 14 .mouseOut {
 15     background: #EDEDED;
 16     width: 200px;
 17 }
 18 </style>
 19 <script type="text/javascript">
 20         var xmlHttp;
 21     //获取用户输入的关联信息的函数
 22     function getMoreContens() {
 23         //获取用户输入
 24         var content = document.getElementById("keyWords").value;
 25         if (content == "") {
 26             clearContent();
 27             return;
 28         }
 29         xmlHttp = createXmlHttp();
 30         //给服务器发送数据
 31         var url = "search?keyword="+encodeURI(content); 
 32         xmlHttp.open("GET",url,true);
 33         xmlHttp.onreadystatechange =     //回调函数
 34             function callback()
 35         {
 36             if(xmlHttp.readyState == 4)
 37                 {
 38                 if(xmlHttp.status == 200){
 39                     var result = decodeURIComponent(xmlHttp.responseText);
 40                     var json = eval("("+result+")");
 41                     clearContent(json);
 42                     intelliSense(json);
 43                 }
 44                 }
 45         };
 46         /*
 47             xmlhttp的send是传递参数用的,但是只有在使用post方式提交请求的时候才有用
 48             如下:
 49             xmlhttp.open("post",url,true); 
 50             ...
 51             xmlhttp.send("data=http://www.mamicode.com/data&data2=data2");
 52              
 53             用get的话一般就是:
 54             xmlhttp.open("get",url,true); 
 55             ...
 56             xmlhttp.send(null);
 57         */
 58         xmlHttp.send(null);
 59     }
 60     
 61     //创建XMLHttpRequest
 62     function createXmlHttp()
 63     {
 64         var xmlHttp;
 65         if(window.XMLHttpRequest)
 66             {
 67             xmlHttp = new XMLHttpRequest();
 68             //兼容某些Mozilla浏览器的响应头,强制设置为text/xml,具体参看:http://www.cnblogs.com/perseverancevictory/p/3690769.html
 69                if(xmlHttp.overrideMimeType){  
 70                    xmlHttp.overrideMimeType("text/xml");
 71                }
 72             }
 73         //兼容IE
 74         else if(window.ActiveXObject)
 75             {
 76             xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
 77             if(!xmlHttp)
 78                 {
 79                 xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
 80                 }
 81             }
 82         return xmlHttp;
 83     }
 84 
 85     function clearContent()
 86     {
 87         var contentTableBody = document.getElementById("content_table_body");
 88         var size = contentTableBody.childNodes.length;
 89         for(var i=size-1;i>0;i--)
 90             {
 91             contentTableBody.removeChild(contentTableBody.childNodes[i]);
 92             }
 93     }
 94     function intelliSense(json)
 95     {
 96         //获取关联数据的长度
 97         var size = json.length;
 98         for(var i=0;i<size;i++)
 99             {
100             var nextNode = json[i];
101             var tr= document.createElement("tr");
102             var td= document.createElement("td");
103             tr.setAttribute("border", "0");
104             tr.setAttribute("bgcolor", "#EDEDED");
105             td.setAttribute("width", "200px");
106             td.onmouseover=function()
107             {
108                 this.className = mouseOver;
109             }
110             td.onmouseout=function()
111             {
112                 this.className = mouseOut;
113             }
114             td.onclick=function()
115             {
116                 document.getElementById("keyWords").value=this.innerText;
117             }
118             var text=document.createTextNode(nextNode);
119             td.appendChild(text);
120             tr.appendChild(td);
121             document.getElementById("content_table_body").appendChild(tr);
122             }
123     }
124 </script>
125 </head>
126 <body>
127     <div>
128         <input type="text"  name="keyWords" id="keyWords"  style="width:200px; height:20px;" onkeyup="getMoreContens()" onfocus="getMoreContens()" onblur="clearContent()" /> <input
129             type="button" id="button" value="百度一下">
130             <div id="popDiv">
131             <table id="content_table">
132                 <tbody id="content_table_body">
133                 </tbody>
134             </table>
135         </div>
136     </div>
137 </body>
138 </html>
search.jsp

 

技术分享
 1 package com.yan.search;
 2 
 3 import java.io.IOException;
 4 import java.net.URLEncoder;
 5 import java.util.ArrayList;
 6 import java.util.List;
 7 
 8 import javax.servlet.ServletException;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 
13 import com.alibaba.fastjson.JSON;
14 
15 public class SearchServlet extends HttpServlet {
16 
17     private static List<String> keyWordList = new ArrayList<String>();
18     static {
19         // 模拟数据
20         keyWordList.add("yanwei");
21         keyWordList.add("yantian");
22         keyWordList.add("yanpeng");
23         keyWordList.add("yanweichao");
24         keyWordList.add("yanweiqi");
25         keyWordList.add("yanyurong");
26         keyWordList.add("yanmeirong");
27         keyWordList.add("yanweichen");
28         keyWordList.add("电影");
29         keyWordList.add("电影 66ys");
30     }
31     private static final long serialVersionUID = 1L;
32 
33     @Override
34     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
35             throws ServletException, IOException {
36         doGet(req, resp);
37     }
38 
39     @Override
40     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
41             throws ServletException, IOException {
42 
43         String keyWord = req.getParameter("keyword");
44         System.out.println(keyWord);
45         List<String> list = keyWord==null?new ArrayList<String>():getDatas(keyWord);
46         String json = JSON.toJSONString(list);
47         //防止乱码
48         String encodeJSON = URLEncoder.encode(json,"UTF-8");
49         resp.getWriter().write(encodeJSON);
50     }
51 
52     public static List<String> getDatas(String keyWord) {
53         List<String> list = new ArrayList<String>();
54         for (int i = 0; i < keyWordList.size(); i++) {
55             if (keyWordList.get(i).contains(keyWord)) {
56                 list.add(keyWordList.get(i));
57             }
58         }
59         return list;
60     }
61 }
SearchServlet.java

 

Servlet+Ajax实现搜索智能提示