📄 面向 java 开发人员的 ajax 构建动态的 java 应用程序.htm
字号:
XMLHttpRequest</SPAN></A></P>
<P>我将从 Ajax 序列的起点开始:创建和分派来自浏览器的
<CODE>XMLHttpRequest</CODE>。不幸的是,不同的浏览器创建
<CODE>XMLHttpRequest</CODE> 的方法各不相同。清单 2 的 JavaScript
函数消除了这些依赖于浏览器的技巧,它可以检测当前浏览器要使用的正确方式,并返回一个可以使用的
<CODE>XMLHttpRequest</CODE>。最好是把它当作辅助代码:只要把它拷贝到 JavaScript 库,并在需要
<CODE>XMLHttpRequest</CODE> 的时候使用它就可以了。</P><BR><BR><A
name=listing2><B>清单 2. 创建跨浏览器的 XMLHttpRequest</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>/*
* Returns a new XMLHttpRequest object, or false if this browser
* doesn't support it
*/
function newXMLHttpRequest() {
var xmlreq = false;
if (window.XMLHttpRequest) {
// Create XMLHttpRequest object in non-Microsoft browsers
xmlreq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// Create XMLHttpRequest via MS ActiveX
try {
// Try to create XMLHttpRequest in later versions
// of Internet Explorer
xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e1) {
// Failed to create required ActiveXObject
try {
// Try version supported by older versions
// of Internet Explorer
xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
// Unable to create an XMLHttpRequest with ActiveX
}
}
}
return xmlreq;
}
</PRE></TD></TR></TBODY></TABLE><BR>
<P>稍后我将讨论处理那些不支持 <CODE>XMLHttpRequest</CODE> 的浏览器的技术。目前,示例假设清单 2 的
<CODE>newXMLHttpRequest</CODE> 函数总能返回 <CODE>XMLHttpRequest</CODE>
实例。</P>
<P>返回示例的购物车场景,我想要当用户在目录项目上点击 Add to Cart 时启动 Ajax 交互。名为
<CODE>addToCart()</CODE> 的 <CODE>onclick</CODE> 处理函数负责通过 Ajax
调用来更新购物车的状态(请参阅 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax1/#listing1">清单
1</A>)。正如清单 3 所示,<CODE>addToCart()</CODE> 需要做的第一件事是通过调用清单 2 的
<CODE>newXMLHttpRequest()</CODE> 函数得到 <CODE>XMLHttpRequest</CODE>
对象。接下来,它注册一个回调函数,用来接收服务器响应(我稍后再详细解释这一步;请参阅 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax1/#listing6">清单
6</A>)。</P>
<P>因为请求会修改服务器上的状态,所以我将用 HTTP <CODE>POST</CODE> 做这个工作。通过
<CODE>POST</CODE> 发送数据要求三个步骤。第一,需要打开与要通信的服务器资源的 <CODE>POST</CODE> 连接
—— 在这个示例中,服务器资源是一个映射到 URL <CODE>cart.do</CODE> 的 servlet。然后,我在
<CODE>XMLHttpRequest</CODE> 上设置一个头,指明请求的内容是表单
编码的数据。最后,我用表单编码的数据作为请求体发送请求。</P>
<P>清单 3 把这些步骤放在了一起。</P><BR><BR><A name=listing3><B>清单 3. 分派 Add to
Cart XMLHttpRequest</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>/*
* Adds an item, identified by its product code, to the shopping cart
* itemCode - product code of the item to add.
*/
function addToCart(itemCode) {
// Obtain an XMLHttpRequest instance
var req = newXMLHttpRequest();
// Set the handler function to receive callback notifications
// from the request object
var handlerFunction = getReadyStateHandler(req, updateCart);
req.onreadystatechange = handlerFunction;
// Open an HTTP POST connection to the shopping cart servlet.
// Third parameter specifies request is asynchronous.
req.open("POST", "cart.do", true);
// Specify that the body of the request contains form data
req.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// Send form encoded data stating that I want to add the
// specified item to the cart.
req.send("action=add&item="+itemCode);
}
</PRE></TD></TR></TBODY></TABLE><BR>
<P>这就是建立 Ajax 往返过程的第一部分,即创建和分派来自客户机的 HTTP 请求。接下来是用来处理请求的 Java
servlet 代码。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/blue_rule.gif"
width="100%"><BR><IMG height=6 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/c.gif" width=8
border=0></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD><IMG height=4 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/c.gif"
width="100%"><BR>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG height=16 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/u_bold.gif"
width=16 border=0><BR></TD>
<TD vAlign=top align=right><A class=fbox
href="http://www.ibm.com/developerworks/cn/java/j-ajax1/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=N1014D><SPAN class=atitle>servlet 请求处理</SPAN></A></P>
<P>用 servlet 处理 <CODE>XMLHttpRequest</CODE>,与处理普通的浏览器 HTTP 请求一样。可以用
<CODE>HttpServletRequest.getParameter()</CODE> 得到在 POST
请求体中发送的表单编码数据。Ajax 请求被放进与来自应用程序的常规 Web 请求一样的
<CODE>HttpSession</CODE> 中。对于示例购物车场景来说,这很有用,因为这让我可以把购物车状态封装在
JavaBean 中,并在请求之间在会话中维持这个状态。</P>
<P>清单 4 是处理 Ajax 请求、更新购物车的简单 servlet 的一部分。<CODE>Cart</CODE> bean
是从用户会话中获得的,并根据请求参数更新它的状态。然后 <CODE>Cart</CODE> 被序列化成 XML,XML 又被写入
<CODE>ServletResponse</CODE>。重要的是把响应的内容类型设置为
<CODE>application/xml</CODE>,否则 <CODE>XMLHttpRequest</CODE>
不会把响应内容解析成 XML DOM。</P><BR><BR><A name=listing4><B>清单 4. 处理 Ajax 请求的
servlet 代码</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>public void doPost(HttpServletRequest req, HttpServletResponse res)
throws java.io.IOException {
Cart cart = getCartFromSession(req);
String action = req.getParameter("action");
String item = req.getParameter("item");
if ((action != null)&&(item != null)) {
// Add or remove items from the Cart
if ("add".equals(action)) {
cart.addItem(item);
} else if ("remove".equals(action)) {
cart.removeItems(item);
}
}
// Serialize the Cart's state to XML
String cartXml = cart.toXml();
// Write XML to response.
res.setContentType("application/xml");
res.getWriter().write(cartXml);
}
</PRE></TD></TR></TBODY></TABLE><BR>
<P>清单 5 显示了 <CODE>Cart.toXml()</CODE> 方法生成的示例 XML。它很简单。请注意
<CODE>cart</CODE> 元素的 <CODE>generated</CODE> 属性,它是
<CODE>System.currentTimeMillis()</CODE> 生成的一个时间戳。</P><BR><BR><A
name=listing5><B>清单 5. Cart 对象的XML 序列化示例 </B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode><?xml version="1.0"?>
<cart generated="1123969988414" total="$171.95">
<item code="hat001">
<name>Hat</name>
<quantity>2</quantity>
</item>
<item code="cha001">
<name>Chair</name>
<quantity>1</quantity>
</item>
<item code="dog001">
<name>Dog</name>
<quantity>1</quantity>
</item>
</cart>
</PRE></TD></TR></TBODY></TABLE><BR>
<P>如果查看应用程序源代码(可以从 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax1/#download">下载</A>
一节得到)中的 Cart.java,可以看到生成 XML 的方式只是把字符串添加在一起。虽然对这个示例来说足够了,但是对于从 Java
代码生成 XML 来说则是最差的方式。我将在这个系列的下一期中介绍一些更好的方式。</P>
<P>现在您已经知道了 <CODE>CartServlet</CODE> 响应 <CODE>XMLHttpRequest</CODE>
的方式。下一件事就是返回客户端,查看如何用 XML 响应更新页面状态。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/blue_rule.gif"
width="100%"><BR><IMG height=6 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/c.gif" width=8
border=0></TD></TR></TBODY></TABLE>
<TABLE class=no-print cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD><IMG height=4 alt=""
src="面向 Java 开发人员的 Ajax 构建动态的 Java 应用程序.files/c.gif"
width="100%"><BR>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -