您的位置:首页 > 其它

Ajax应用---实现自动提示功能

2017-08-07 16:15 274 查看
本例主要利用Ajax实现如下图的自动提示功能,且内容始终和服务器端数据库内容一致:



核心代码如下:

1. JSP文件用于显示基本界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Auto-Complete</title>
</head>
<script type="text/javascript" charset="GBK" src="js3.js" ></script>
<body>
<table style="border-collapse: collapse;" bordercolor="#666666"
cellspacing="0" cellpadding="2" width="400" bgcolor="#f5efe7" border="0">
<tr>
<td align="center" height="20" colspan="3">
<b>学员信息搜索</b>
</td>
</tr>
<tr>
<td height="20">输入学生姓名:</td>
<td height="20">
<input type="text" size="15" id="name" onkeyup="findNames();" height="20">
<div style="position:absolute" id="popup">
<table id="complete_table" bgcolor="#FFFAFA" border="0" cellspacing="0" cellpadding="0">
<tbody id="complete_body" style="cursor:pointer"></tbody>
</table>
</div>
</td>
<td height="20"><img alt="图片加载失败" src="images/search.png" height="20" onclick="search();"></td>
</tr>
<tr>
<td height="20" align="left">学员情况:</td>
<td id="pos_1" height="80">
<textarea id="content"></textarea>
</td>
</tr>
</table>
</body>
</html>


2. JS文件实现‘服务器-客户端’通信操作

var XMLHttpReq;
var completeDiv;
var inputField;
var completeTable;
var completeBody;

function createXMLHttpRequest() {
if (window.XMLHttpRequest) {// Mozilla 浏览器
XMLHttpReq = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 浏览器
try {
XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
}
//搜索请求函数
function search(){
var sortName = document.getElementById("name");
createXMLHttpRequest();
var url = "autoComplete?action=search&name="+encodeURI(inputField.value);
XMLHttpReq.open("GET",url,true);
XMLHttpReq.onreadystatechange = processSearchResponse;
XMLHttpReq.send(null);
}
function processSearchResponse(){
if (XMLHttpReq.readyState == 4) {// 判断对象状态,4则说明服务器响应已完成,可以访问了
if (XMLHttpReq.status == 200) {// 信息已经成功返回,开始处理信息
var res = XMLHttpReq.responseXML.getElementsByTagName("res");
if (res.length>0){
document.getElementById("content").value = res[0].firstChild.data;
}
} else {
window.alert("您所请求的页面有异常!");
}
}
}
//查找匹配的名字
function findNames(){
inputField = document.getElementById("name");//获取输入的字符
completeTable = document.getElementById("complete_table");//显示查询结果的表
completeDiv = document.getElementById("popup");//显示查询结果表的显示区域
completeBody = document.getElementById("complete_body");//显示查询结果表的主体
if(inputField.value.length>0&&inputField.value!=" "){
createXMLHttpRequest();
var url = "autoComplete?action=match&name="+encodeURI(inputField.value);
XMLHttpReq.open("GET",url,true);
XMLHttpReq.onreadystatechange = processMatchResponse;
XMLHttpReq.send(null);
}else{
clearNames();//如果未输入则清除显示区域内容
}
}
function processMatchResponse() {
if (XMLHttpReq.readyState == 4) {// 判断对象状态,4则说明服务器响应已完成,可以访问了
if (XMLHttpReq.status == 200) {// 信息已经成功返回,开始处理信息
setNames(XMLHttpReq.responseXML.getElementsByTagName("res"));
} else {
window.alert("您所请求的页面有异常!");
}
}
}
//生成与输入内容匹配行
function setNames(names){
clearNames();
var size = names.length;//可能的名字有很多个,获取其数目
setOffsets();//设置显示的位置
var row,cell,txtNode;
for(var i=0;i<size;i++){
var nextNode = names[i].firstChild.nodeValue;//获取文本节点的值
row = document.createElement("tr");
cell= document.createElement("td");

cell.setAttribute("bgcolor","#FFFAFA");
cell.onclick = function(){completeField(this)};

txtNode = document.createTextNode(nextNode);
cell.appendChild(txtNode);
row.appendChild(cell);
completeBody.appendChild(row);
}
}
//设置显示位置
function setOffsets(){
completeTable.style.width = inputField.offsetWidth+"px";//提示框宽度和输入框一致
var left = calculateOffset(inputField,"offsetLeft");
var top = calculateOffset(inputField,"offsetTop")+inputField.offsetHeight;
completeDiv.style.border = "black 1px solid";//设置区域的边框是黑实线
completeDiv.style.left = left +"px";
completeDiv.style.top = top +"px";
}
//计算显示位置
function calculateOffset(field,attr){
var offset = 0;
while(field){
offset+=field[attr];//返回当前元素左边缘距离offsetParent属性返回元素的距离,单位是像素。
field = field.offsetParent;
}
return offset;
}
//填写输入框
function completeField(cell){
inputField.value = cell.firstChild.nodeValue;
clearNames();
}
//清除自动完成的行
function clearNames(){
var end = completeBody.childNodes.length;
for(var i=end-1;i>=0;i--){
completeBody.removeChild(completeBody.childNodes[i]);
}
completeDiv.style.border = "none";
}


3. 服务器端的java文件

package servletdemo;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mysql.fabric.Response;

@WebServlet("/AutoCompleteAction")
public class AutoCompleteAction extends HttpServlet {
private static final lon
c098
g serialVersionUID = 1L;

public AutoCompleteAction() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String action = request.getParameter("action");
//String name = request.getParameter("name");
String queryStr = URLDecoder.decode(request.getQueryString() , "utf-8");
String[] paramPairs = queryStr.split("&");
String name = paramPairs[1].split("=")[1];

response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");

PrintWriter out = response.getWriter();
out.println("<response>");
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/DB_student?useUnicode=true&characterEncoding=GBK";
String user = "root";
String password = "admin";
Connection con = DriverManager.getConnection(url,user,password);
Statement stat = con.createStatement();
ResultSet rs = null;
if("match".equals(action)){
String sql ="select * from stuscore where name like '"+name+"%'";
rs = stat.executeQuery(sql);
while(rs.next()){
out.println("<res>"+rs.getString("name")+"</res>");
}
}else if("search".equals(action)){
String sql ="select grade from stuscore where name='"+name+"'";
rs = stat.executeQuery(sql);
if(rs.next()){
out.println("<res>"+rs.getString("grade")+"</res>");
}
}
rs.close();
stat.close();
con.close();
}catch (Exception e) {
e.printStackTrace();
}
out.println("</response>");
out.close();
}
}


这里开始是发现server.xml里面配置了

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="gbk"/>
里的
URIEncoding="gbk"
,导致使用

String name = request.getParameter("name");
时服务器使用gbk对utf-8编码的url进行解码,故产生乱码,将
URIEncoding="gbk"
去掉或者改成
URIEncoding="utf-8"
即可。

使用下面方法则可以不管server.xml里配置了什么都可以正常解码:

`String queryStr = URLDecoder.decode(request.getQueryString() , “utf-8”);

原因分析:

`首先get方法用request.setCharacterEncoding(“UTF-8”)来解决乱码问题是不行的,因为在Tomcat5.0以上版本中,默认情况下使用ISO- 8859-1对URL提交的数据和表单中GET方式提交的数据进行重新编解码。使用getParameter时,Tomcat默认是用iso-8859-1先将原本utf-8编码的url使用iso-8859-1进行解码,故使用getParameter时会得到乱码;(疑问:为什么上面测试时可以将URIEncoding去掉也可以正确解码,是否说明默认解码方式为utf-8?)

而对于getQueryString,tomcat没有对其进行decode操作,保留了原有的urlencoding编码方式,所以在后面的使用过程中,如果利用utf-8对其解码,就不会出现乱码。

4. xml文件配置

<servlet>
<servlet-name>AutoCompleteAction</servlet-name>
<servlet-class>servletdemo.AutoCompleteAction</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AutoCompleteAction</servlet-name>
<url-pattern>/autoComplete</url-pattern>
</servlet-mapping>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: