Servlet和ajax实现搜索框智能提示
一、理论分析
1.在搜索框中输入关键字;
2.浏览器将关键字异步发送给服务器;
3.服务器经过处理,将相应的数据以json格式返回给客户端;
4.客户端接收到服务器的响应数据,解析之后使用js操作dom显示数据。
流程图:
一共有两个重点:1)数据交互采用ajax方式;2)javascript解析数据动态展示。
二、动手实践
1.实现前台页面功能;2.实现后台处理程序
前台(search.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style type="text/css">
#mydiv{
position:absolute;
left:50%;
top:50%;
margin-left:-200px;
margin-top:-50px;
}
.mouseOver{
background:#708090,
color:#FFFAFA;
}
.mouseOut{
background:#FFFAFA,
color:#000000;
}
</style>
<script type="text/javascript">
//获得用户输入内容的关联信息的函数
function getMoreContents(){
var xmlHttp;
//首先要获得用户的输入内容的关联信息的函数
var content=document.getElementById("keyword");
if(content.value==""){
//这个是为了当没有删除输入框中的数据以后,关联数据也不会显示
clearContent();
return;
}
<!--alert(content.value);-->
//然后要给服务器发送用户输入的内容,因为我们采用的是ajax异步发送数据,
//所以我们要使用一个对象,叫做XmlHttp对象
xmlHttp=createXmlHttp();
<!--alert(xmlHttp);-->
//要给服务器发送数据
var url="search?keyword="+escape(content.value);
//true表示javascript脚本会在send()方法之后继续执行,而不会等待来自服务器的响应
xmlHttp.open("GET",url,true);
//xmlHttp绑定回调方法,这个回调方法会在xmlHttp状态改变的时候被调用
//xmlHttp的状态0-4,我们只关心4(complete)这个状态
//当完成之后,在调用回调方法才有意义
xmlHttp.onreadystatechange=callback;
xmlHttp.send(null);
}
//获得XmlHttp对象
function createXmlHttp(){
//对于大多数的浏览器都适用
var xmlHttp;
if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
//要考虑浏览器的兼容性
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
if(!xmlHttp){
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
}
return xmlHttp;
}
//回调函数
function callback(){
//4代表成功
if(xmlHttp.readyState==4){
//200代表服务器响应成功
//404代表资源未找到,500代表服务器内部错误
if(xmlHttp.status==200){
//交互成功,获得相应的数据,是文本格式
var result=xmlHttp.responseText;
//解析获得数据
var json=eval("("+result+")");
//获得数据之后,就可以动态的显示这些数据了,把这些数据展示到
//输入框的下面
//alert(json);
setContent(json);
}
}
}
//设置关联数据的展示,参数代表的是服务器传递过来的关联数据
function setContent(contents){
clearContent();
//首先获得关联数据的长度,以此来确定生成多少<tr></tr>
//先设置位置
setLocation();
var size=contents.length;
//设置内容
for(var i=0;i<size;i++){
var nextNode=contents[i];//代表的是json格式数据的第i个函数
var tr=document.createElement("tr");
var td=document.createElement("td");
td.setAttribute("border","0");
td.setAttribute("bgcolor","#FFFAFA");
<!--鼠标经过的时候-->
td.onmouseover=function(){
this.className='mouseOver';
};
<!--鼠标退出的时候-->
td.onmouseout=function(){
this.className='mouseOut';
};
td.onmousedown=function(){
//这个方法实现的是,当用鼠标点击选择一个关联的数据时,(自动填充)关联数据自动设置为输入框的数据
document.getElementById("keyword").value=this.innerHTML;
//清除div边框
document.getElementById("popDiv").style.border="none";
};
var text=document.createTextNode(nextNode);
td.appendChild(text);
tr.appendChild(td);
document.getElementById("content_table_body").appendChild(tr);
}
}
//清空之前的数据
function clearContent(){
var contentTableBody=document.getElementById("content_table_body");
var size=contentTableBody.childNodes.length;
for(var i=size-1;i>=0;i--){
contentTableBody.removeChild(contentTableBody.childNodes[i]);
}
//清空边框
document.getElementById("popDiv").style.border="none";
}
//当输入框失去焦点的时候,关联信息清空
function keywordBlur(){
clearContent();
}
//用来设置显示关联信息的位置
function setLocation(){
//关联信息的显示位置大小要和输入框一致
var content=document.getElementById("keyword");
var width=content.offsetWidth;//输入框的宽度
var left=content["offsetLeft"];//距离左边框的距离
var top=content["offsetTop"]+content.offsetHeight;//到顶部的距离
//获得显示数据的div
var popDiv=document.getElementById("popDiv");
popDiv.border="black 1px solid";
popDiv.style.left=left+"px";
popDiv.style.top=top+"px";
popDiv.style.width=width+"px";
document.getElementById("content_table").style.width=width+"px";
}
</script>
</head>
<body>
<div id="mydiv">
<!-- 输入框 -->
<!-- 获得焦点时候onfocus,要重新与服务器进行交互;失去焦点时候,onblur,就清空关联数据 -->
<input type="text" size="50" id="keyword" onkeyup="getMoreContents()"
onblur="keywordBlur()" onfocus="getMoreContents()"/>
<input type="button" value="百度一下" width="50px"/>
<!-- 下面是内容展示的区域 -->
<div id="popDiv">
<table id="content_table" bgcolor="#FFFAFA" border="0"cellspacing="0" cellpadding="0">
<tbody id="content_table_body">
<!-- 动态查询出来的数据显示在这个地方 -->
<!--
<tr><td>ajax</td></tr>
<tr><td>ajax1</td></tr>
<tr><td>ajax2</td></tr>
-->
</tbody>
</table>
</div>
</div>
</body>
</html>
后台(SearchServlet.java)
package com.imooc;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
public class SearchServlet extends HttpServlet {
//定义一个容器
static List<String> datas=new ArrayList<String>();
static {
//这些是模拟数据
datas.add("ajax");
datas.add("ajax post");
datas.add("becky");
datas.add("bill");
datas.add("james");
datas.add("jerry");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doGet(req, resp);
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
System.out.println("123");
//首先获得客户端发送来的数据keyword
String keyword=request.getParameter("keyword");
//获得关键字之后进行处理,得到关联数据
List<String> listData=getData(keyword);
//返回json格式
//下面这个语句是指在后台打印
System.out.println(JSONArray.fromObject(listData));
System.out.println(JSONArray.fromObject(listData).toString());
//把这些数据传到前台去,好像这里有问题,到这里就不调试了?
response.getWriter().write(JSONArray.fromObject(listData).toString());
}
//获得关联数据的方法
public List<String> getData(String keyword){
List<String> list=new ArrayList<String>();
for(String data:datas) {
if(data.contains(keyword)) {
list.add(data);
}
}
return list;
//return null;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ajax_Test</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>search.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>search</servlet-name>
<servlet-class>com.imooc.SearchServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>search</servlet-name>
<!-- url在search.jsp中定义了 var url="search?keyword="+escape(content.value);
-->
<url-pattern>/search</url-pattern>
</servlet-mapping>
</web-app>
效果图(类似百度的):