资源描述
这些时间,瞎子也看得见,AJAX正大踏步朝咱们走来。不管咱们是拥护也好,反对也罢,还是视而不见,AJAX像一阵时尚,席转了咱们所有人。
有关AJAX定义也好,大话也好,早有人在网上刊登了汗牛充栋文字,在这里我也不想照本宣科。
只想说说我感觉到某些长处,对于不对,人们也可以和我讨论:
首先是异步交互,顾客感觉不到页面提交,当然也不等待页面返回。这是使用了AJAX技术页面给顾客第一感觉。
另首先是响应速度快,这也是顾客强烈体验。
然后是与咱们开发者有关,复杂UI成功处理,一直以来,咱们对B/S模式UI不如C/S模式UI丰富而苦恼。目前由于AJAX大量使用JS,使得复杂UI设计变得愈加成功。
最终,AJAX祈求返回对象为XML文献,这也是一种时尚,就是WEB SERVICE时尚同样。易于和WEB SERVICE结合起来。
好了,闲话少说,让咱们转入正题吧。
咱们第一种例子是基于Servlet为后台一种web应用。
基于ServletAJAX
这是一种很常用UI,当顾客在第一种选用框里选用ZHEJIANG时,第二个选用框要出现ZHEJIANG都市;当顾客在第一种选用框里选用JIANGSU时,第二个选用框里要出现JIANGSU都市。
首先,咱们来看配置文献web.xml,在里面配置一种servlet,跟往常同样:
<web-app version="2.4"
xmlns=""
xmlns:xsi=""
xsi:schemaLocation="
">
<servlet>
<servlet-name>SelectCityServlet</servlet-name>
<servlet-class>com.stephen.servlet.SelectCityServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SelectCityServlet</servlet-name>
<url-pattern>/servlet/SelectCityServlet</url-pattern>
</servlet-mapping>
</web-app>
然后,来看咱们JSP文献:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>MyHtml.html</title>
<meta -equiv="keywords" content="keyword1,keyword2,keyword3">
<meta -equiv="description" content="this is my page">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
</head>
<script type="text/javascript">
function getResult(stateVal) {
var url = "servlet/SelectCityServlet?state="+stateVal;
if (window.XML Request) {
req = new XML Request();
}else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XML ");
}
if(req){
req.open("GET",url,true);
req.onreadystatechange = complete;
req.send(null);
}
}
function complete(){
if (req.readyState == 4) {
if (req.status == 200) {
var city = req.responseXML.getElementsByTagName("city");
file://alert(city.length);
var str=new Array();
for(var i=0;i<city.length;i++){
str[i]=city[i].firstChild.data;
}
file://alert(document.getElementById("city"));
buildSelect(str,document.getElementById("city"));
}
}
}
function buildSelect(str,sel) {
sel.options.length=0;
for(var i=0;i<str.length;i++) {
sel.options[sel.options.length]=new Option(str[i],str[i])
}
}
</script>
<body>
<select name="state" onChange="getResult(this.value)">
<option value="">Select</option>>
<option value="zj">ZEHJIANG</option>>
<option value="zs">JIANGSU</option>>
</select>
<select id="city">
<option value="">CITY</option>
</select>
</body>
</html>
第一眼看来,跟咱们寻常JSP没有两样。仔细一看,不一样在JS里头。
咱们首先来看第一种措施:getResult(stateVal),在这个措施里,首先是获得Xml Request;然后设置该祈求url:req.open("GET",url,true);接着设置祈求返回值接受措施:req.onreadystatechange = complete;该返回值接受措施为——complete();最终是发送祈求:req.send(null);
然后咱们来看咱们返回值接受措施:complete(),这这个措施里,首先判断与否对旳返回,假如对旳返回,用DOM对返回XML文献进行解析。有关DOM使用,这里不再讲述,请人们参阅有关文档。得到city值后来,再通过buildSelect(str,sel)措施赋值到对应选用框里头去。
最终咱们来看看Servlet文献:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet. . Servlet;
import javax.servlet. . ServletRequest;
import javax.servlet. . ServletResponse;
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class SelectCityServlet extends Servlet {
public SelectCityServlet() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet( ServletRequest request, ServletResponse response)
throws ServletException,IOException {
response.setContentType("text/xml");
response.setHeader("Cache-Control","no-cache");
String state = request.getParameter("state");
StringBuffer sb=new StringBuffer("<state>");
if ("zj".equals(state)){
sb.append("<city>hangzhou</city><city>huzhou</city>");
} else if("zs".equals(state)){
sb.append("<city>nanjing</city><city>yangzhou</city><city>suzhou</city>");
}
sb.append("</state>");
PrintWriter out=response.getWriter();
out.write(sb.toString());
out.close();
}
}
这个类也十分简朴,首先是从request里获得state参数,然后根据state参数生成对应XML文献,最终将XML文献输出到PrintWriter对象里。
到目前为止,第一种例子代码已经所有结束。是不是比较简朴?
运行图:
/
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta -equiv="Content-type" content="text/html;charset=utf-8">
<title>多级联动菜单</title>
<script type="text/javascript">
var xml ; //用于保留XML Request对象全局变量
var targetSelId; //用于保留要更新选项列表id
var selArray; //用于保留级联菜单id数组
//用于创立XML Request对象
function createXml () {
//根据window.XML Request对象与否存在使用不一样创立方式
if (window.XML Request) {
xml = new XML Request(); //FireFox、Opera等浏览器支持创立方式
} else {
xml = new ActiveXObject("Microsoft.XML ");//IE浏览器支持创立方式
}
}
//获取列表选项调用函数
function buildSelect(selectedId,targetId) {
if (selectedId == "") { //selectedId为空串体现选中了默认项
clearSubSel(targetId); //清除目旳列表及下级列表中选项
return; //直接结束函数调用,不必向服务器祈求信息
}
targetSelId = targetId; //将传入目旳列表id赋值给targetSelId变量
createXml (); //创立Xml Request对象
xml .onreadystatechange = buildSelectCallBack; //设置回调函数
xml .open("GET","select_menu.jsp?selectedId=" + selectedId,true);
xml .send(null);
}
//获取列表选项回调函数
function buildSelectCallBack() {
if (xml .readyState == 4) {
var optionsInfo = eval("("+xml .responseText+")"); //将从服务器获得文本转为对象直接量
var targetSelNode = document.getElementById(targetSelId);
clearSubSel(targetSelId); //清除目旳列表中选项
//遍历对象直接量中组员
for (var o in optionsInfo) {
targetSelNode.appendChild(createOption(o,optionsInfo[o]));//在目旳列表追加新选项
}
}
}
//根据传入value和text创立选项
function createOption(value,text) {
var opt = document.createElement("option"); //创立一种option节点
opt.setAttribute("value",value); //设置value
opt.appendChild(document.createTextNode(text)); //给节点加入文本信息
return opt;
}
//清除传入列表节点内所有选项
function clearOptions(selNode) {
selNode.length = 1; //设置列表长度为1,仅保留默认选项
selNode.options[0].selected = true; //选中默认选项
}
//初始化列表数组(按级别)
function initSelArray() {
selArray = arguments; //arguments对象包括了传入所有参数
}
//清除下级子列表选项
function clearSubSel(targetId) {
var canClear = false; //设置清除开关,初始值为假
for (var i=0;i<selArray.length;i++) { //遍历列表数组
if (selArray[i]==targetId) { //当遍历至目旳列表时,打开清除开关
canClear = true;
}
if (canClear) { //从目旳列表开始到最下级列表结束,开关一直保持打开
clearOptions(document.getElementById(selArray[i])); //清除该级列表选项
}
}
}
</script>
</head>
<!-- 页面加载完毕做两件事:1.初始化列表数组 2.为第一种列表赋值 -->
<body onload="initSelArray('selA','selB','selC');buildSelect('INIT','selA')">
<h1>多级联动菜单</h1>
<table>
<tr>
<td>列表A</td>
<td>
<select name="selA" id="selA" onchange="buildSelect(this.value,'selB')">
<option value="" selected>------请选用------</option>
</select>
</td>
</tr>
<tr>
<td>列表B</td>
<td>
<select name="selB" id="selB" onchange="buildSelect(this.value,'selC')">
<option value="" selected>------请选用------</option>
</select>
</td>
</tr>
<tr>
<td>列表C</td>
<td>
<select name="selC" id="selC">
<option value="" selected>------请选用------</option>
</select>
</td>
</tr>
</table>
</body>
</html>
<%@ page contentType="text/plain;charset=UTF-8"%>
<%@ page language="java"%>
<%@ page import="java.sql.*,ajax.db.DBUtils"%>
<%!
//访问数据库获得下级选项信息
String getOptions(String selectedId) {
int counter = 0; //计数器
StringBuffer opts = new StringBuffer("{"); //保留选项信息
String sql = "select * from select_menu where pid = ?order by seq asc";//定义查询数据库SQL语句
Connection conn = null; //申明Connection对象
PreparedStatement pstmt = null; //申明PreparedStatement对象
ResultSet rs = null; //申明ResultSet对象
try {
conn = DBUtils.getConnection(); //获取数据库连接
pstmt = conn.prepareStatement(sql);//根据sql创立PreparedStatement
pstmt.setString(1,selectedId); //设置参数
rs = pstmt.executeQuery(); //执行查询,返回成果集
while (rs.next()) { //遍历成果集
//假如不是第一项,追加一种“,”用于分隔选项
if (counter > 0) {
opts.append(",");
}
opts.append("'");
opts.append(rs.getString("id"));
opts.append("':'");
opts.append(rs.getString("text"));
opts.append("'");
counter++; //计数器加1
}
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
DBUtils.close(rs); //关闭成果集
DBUtils.close(pstmt); //关闭PreparedStatement
DBUtils.close(conn); //关闭连接
}
opts.append("}");
return opts.toString();
}
%>
<%
out.clear(); //清空目前输出内容(空格和换行符)
String selectedId = request.getParameter("selectedId");//获取selectedId参数
String optionsInfo = getOptions(selectedId); //调用getOptions措施获得下级选项信息
out.print(optionsInfo); //输出下级选项信息
%>
<%@ page contentType="text/plain;charset=UTF-8"%>
<%@ page language="java"%>
<%@ page import="java.sql.*,ajax.db.DBUtils"%>
<%!
//访问数据库获得下级选项信息
String getOptions(String selectedId) {
int counter = 0; //计数器
StringBuffer opts = new StringBuffer("{"); //保留选项信息
String sql = "select * from select_menu where pid = ?order by seq asc";//定义查询数据库SQL语句
Connection conn = null; //申明Connection对象
PreparedStatement pstmt = null; //申明PreparedStatement对象
ResultSet rs = null; //申明ResultSet对象
try {
conn = DBUtils.getConnection(); //获取数据库连接
pstmt = conn.prepareStatement(sql);//根据sql创立PreparedStatement
pstmt.setString(1,selectedId); //设置参数
rs = pstmt.executeQuery(); //执行查询,返回成果集
while (rs.next()) { //遍历成果集
//假如不是第一项,追加一种“,”用于分隔选项
if (counter > 0) {
opts.append(",");
}
opts.append("'");
opts.append(rs.getString("id"));
opts.append("':'");
opts.append(rs.getString("text"));
opts.append("'");
counter++; //计数器加1
}
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
DBUtils.close(rs); //关闭成果集
DBUtils.close(pstmt); //关闭PreparedStatement
DBUtils.close(conn); //关闭连接
}
opts.append("}");
return opts.toString();
}
%>
<%
out.clear(); //清空目前输出内容(空格和换行符)
String selectedId = request.getParameter("selectedId");//获取selectedId参数
String optionsInfo = getOptions(selectedId); //调用getOptions措施获得下级选项信息
out.print(optionsInfo); //输出下级选项信息
%>
展开阅读全文