教材用的是《精通Java Web整合开发(第2版)》。这本书样例丰富,原理讲的不多,就照着例子写了几个Ajax的实现。
写的demo,实现根据输入的查询条件查询数据库得到一些数据,然后展现页面里,只展现一条记录。通过下拉框选择其它记录时,本条记录的其它列信息也动态刷新。
核心架构组织,由Servlet配置实现,Ajax使用Jsp自带整合的Ajax功能,大致结构图如下:
入口为querySubmit.jsp提交页,一个简单的form表单,body部分源码如下:
<body>
<form name="qForm" action="QueryUser" method="post">
请输入职位条件:<input type="text" name="role">
<input type="submit" value="查询">
</form>
</body>
QueryUser.java接收传递的查询条件,实现数据查询操作(这里涉及简单的JDBC操作):
package com.servlet.db;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.sqlException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class QueryUser
extends HttpServlet
{
private static final long serialVersionUID = 1L;
private String driver;
private String url;
private String user;
private String pass;
@Override
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
//配置文件配置的数据库驱动、url、数据库登录名、登录密码
ServletConfig conf = getServletConfig();
driver = conf.getInitParameter("driver");
url = conf.getInitParameter("url");
user = conf.getInitParameter("user");
pass = conf.getInitParameter("pass");
System.out.println("数据库驱动:"+driver);
System.out.println("数据URL:"+url);
System.out.println("数据库登录名:"+user);
System.out.println("数据库密码:"+pass);
}
@Override
public void service(HttpServletRequest request,HttpServletResponse response)
throws IOException
{
System.out.println("service方法进入...");
response.setContentType("text/html");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String role = request.getParameter("role");
System.out.println("Role is:"+role);
List<User> userList = new ArrayList<User>();
try
{
Class.forName(driver);
Connection conn = DriverManager.getConnection(url,user,pass);
PreparedStatement pst = conn.prepareStatement("select * from test where role = ?");
pst.setString(1,role);
ResultSet rs = pst.executeQuery();
User userInfo;
//String sTemp;
while (rs.next()){
userInfo = new User();
//取出来的默认为iso8859-1编码,转换为gb2312,否则乱码//若在驱动url中设置了编码格式,就不需要解码了
//sTemp = new String(rs.getString(1).getBytes("iso8859-1"),"GB2312");
userInfo.setAddress(rs.getString(1).trim());
//sTemp = new String(rs.getString(2).getBytes("iso8859-1"),"GB2312");
userInfo.setTel(rs.getString(2).trim());
//sTemp = new String(rs.getString(3).getBytes("iso8859-1"),"GB2312");
userInfo.setName(rs.getString(3).trim());
System.out.println("User is:" + userInfo);
userList.add(userInfo);
}
rs.close();
conn.close();
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (sqlException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpSession session = request.getSession();
//成员列表放Session里
session.setAttribute("userList",userList);
response.sendRedirect("selectUser.jsp");//查询结束,实现页面跳转
System.out.println("service方法结束.");
}
}
数据实体类User.java:
package com.servlet.db;
public class User
{
private String address;
private String tel;
private String name;
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address = address;
}
public String getTel()
{
return tel;
}
public void setTel(String tel)
{
this.tel = tel;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String toString()
{
return "address:" + address + ",tel:" + tel + ",name:" + name + ".";
}
}
表结构创建sql:
create table test
(
address char(20),phone char(20),name char(10),role char(10)
)
数据库相关信息,在配置文件中配置。
如果大家注意到数据库结果集处理的注释的话,会发现这里涉及一些数据库转码的问题。这里纠结了很久,最后参考项目中数据库连接的url,实现了修改连接数据库,字符集编码的问题。这个问题等搞清楚了url的这个配置格式是否通用后,再写个总结给大家参考下。
接下来就是展现页面,也是Ajax核心处理jsp,selectUser.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.servlet.db.User"%>
<%
String path = request.getContextPath();
String basePath =
request.getScheme() + "://" + request.getServerName() + ":"
+ request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>动态更新下拉列表</title>
<Meta http-equiv="pragma" content="no-cache">
<Meta http-equiv="cache-control" content="no-cache">
<Meta http-equiv="expires" content="0">
<Meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<Meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<%
//从session取值
List<User> userList = (List<User>) session.getAttribute("userList");
List<String> addressSelect = new ArrayList<String>();
//初始化地址列表
if (userList != null)
{
for (User item : userList)
{
addressSelect.add(item.getAddress());
}
}
%>
<script type="text/javascript">
var xmlHttp;
//创建XMLHttpRequest
function createXMLHttpRequest(){
if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}
}
//响应用户列表的onChange事件的处理方法
function updateSelect(){
var selected = document.all.slt1.value;
//为-1,清空操作
if(selected == -1){
document.all.tele.value="";
document.all.name.value="";
return;
}
//不为0,启用ajax
//状态触发器绑定到processor函数
createXMLHttpRequest();
xmlHttp.onreadystatechange = processor;
xmlHttp.open("GET","GetTargetUser?targetAddress="+selected);
xmlHttp.send(null);
}
//处理状态改变的函数
function processor(){
var result;
if(xmlHttp.readyState==4){//响应完成
if(xmlHttp.status==200){//返回成功
result = xmlHttp.responseXML.getElementsByTagName("user");
document.all.tele.value=result[0].childNodes[0].childNodes[0].nodeValue;
document.all.name.value=result[0].childNodes[1].childNodes[0].nodeValue;
}
}
}
</script>
<body>
请选择地址:
<select id="slt1" onChange="updateSelect()">
<option value="-1"></option>
<%
for (int i=0;i<addressSelect.size();i++)
{
%>
<option value="<%=i%>"><%=addressSelect.get(i)%></option>
<%
}
%>
</select>
电话:
<input type="text" id="tele" />
姓名:
<input type="text" id="name" />
</body>
</html>
这里总结下Ajax使用顺序:
1. 在javascript区域内定义Ajax的xmlHttp变量;
2. 定义创建XMLHttpRequest方法,此方法根据浏览器不同,创建xmlHttp的异步请求对象;
3. 定义处理Ajax状态改变的函数,处理Ajax异步请求对应的异步响应,根据响应结果对当前页面做改动操作;
4. 定义响应用户列表的onChange事件的处理方法。方法先调用“创建XMLHttpRequest函数”,实例化一个新的xmlHttp异步请求对象,然后将此xmlHttp状态触发器绑定到“处理Ajax状态改变的函数”,最后使用open、send方法,发送异步请求。
接下来就是Ajax异步请求处理的servlet类,GetTargetUser.java:
package com.ajax;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.servlet.db.User;
public class GetTargetUser
extends HttpServlet
{
public void destroy()
{
super.destroy();
}
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException
{
doPost(req,resp);
}
@SuppressWarnings("unchecked")
@Override
protected void doPost(HttpServletRequest req,IOException
{
System.out.println("GetTargetUser...");
//获取查询条件
int targetIndex = Integer.valueOf(req.getParameter("targetAddress"));
//从session取值
List<User> userList = (List<User>) req.getSession().getAttribute("userList");
User user = null;
if (targetIndex < userList.size())
{
user = userList.get(targetIndex);
}
if (null != user)
{
System.out.println("process user...");
//查询结果以XML文档返回给客户端
resp.setContentType("text/xml");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
//user
out.println("<response>");
out.println("<user>");
out.println("<tele>" + user.getTel() + "</tele>");
out.println("<name>" + user.getName() + "</name>");
out.println("</user>");
out.println("</response>");
out.flush();
out.close();
}
}
}
最后就是web.xml关于servlet的配置了:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>querySubmit.jsp</welcome-file>
</welcome-file-list>
<!-- 若为class,servlet下的init-param放到init方法的参数config下 -->
<servlet>
<servlet-name>QueryUser</servlet-name>
<servlet-class>com.servlet.db.QueryUser</servlet-class>
<init-param>
<param-name>driver</param-name>
<param-value>com.informix.jdbc.IfxDriver</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>
jdbc:informix-sqli://ip:port/dbname:INFORMIXSERVER=dbserverName;CLIENT_LOCALE=en_US.GB2312-80;DB_LOCALE=en_US.8859-1;NEWLOCALE=en_US,en_US;NEWCODESET=GB2312,8859-1,819
</param-value>
</init-param>
<init-param>
<param-name>user</param-name>
<param-value>Tommy</param-value>
</init-param>
<init-param>
<param-name>pass</param-name>
<param-value>T</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>QueryUser</servlet-name>
<url-pattern>/QueryUser</url-pattern>
</servlet-mapping>
<!-- ajax学习 -->
<servlet>
<servlet-name>GetTargetUser</servlet-name>
<servlet-class>com.ajax.GetTargetUser</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetTargetUser</servlet-name>
<url-pattern>/GetTargetUser</url-pattern>
</servlet-mapping>
</web-app>
这里数据库用的是Informix,其配置的URL中包含对CLIENT_LOCALE与DB_LOCALE的转换配置关系:从GB2312到8859-1。暂时没有验证其它数据库使用时,这种转换关系是什么样的,如果有知道的朋友,欢迎留言指导一下。
提交页面
展现页面
动态选择1
动态选择2
至此,一个简单的Ajax动态展现数据库中的用户信息的demo实现了,希望对初学Ajax、Servlet、JDBC的同学们有所帮助。同样也欢迎路过的“高年级”同学予以指导,不胜感激。
原文链接:https://www.f2er.com/ajax/166056.html