📄 面向 java 开发人员的 ajax ajax 的 java 对象序列化.htm
字号:
<name><c:out value="${item.name}" escapeXml="true"/></name>
<price>${item.formattedPrice}</price>
</item>
</c:forEach>
</items>
</order>
</c:forEach>
</orderhistory>
</PRE></TD></TR></TBODY></TABLE><BR>
<P>这个简洁的模板只输出订单历史视图需要的数据,不输出不相关的资料(例如商品说明)。创建产品搜索视图的定制 XML
应当同样简单,这个视图包含每个商品的完整说明和库存水平。</P>
<P><A name=N10194><SPAN class=smalltitle>模板的问题</SPAN></A></P>
<P>另一方面,现在我需要为每个不同视图创建一个新
JSP,而不能仅仅把需要的对象图组织起来并序列化它。从设计的角度来说,许多人可能会有争议,认为这无论如何是件好事,因为这意味着正式地考虑服务器要生成的文档类型。而且,因为我现在要处理通用的模板环境,而不是特定于
XML 的 API,所以确保标记匹配、元素和属性的顺序正确以及 XML 实体(例如 <CODE><</CODE> 或
<CODE>&</CODE>)正确转义就成了我的责任。JSP 的核心 <CODE>out</CODE>
标记使后面这项工作变得很容易,但是不是所有的模板技术都提供了这样的机制。最后,没有方便的途径可以在服务器端根据方案检验生成的 XML
文档的正确性,但这毕竟不是要在生产环境中做的事,可以方便地在开发期间处理它。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=""
src="面向 Java 开发人员的 Ajax Ajax 的 Java 对象序列化.files/blue_rule.gif"
width="100%"><BR><IMG height=6 alt=""
src="面向 Java 开发人员的 Ajax 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 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 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-ajax2/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=N101A9><SPAN class=atitle>不用 XML 的响应数据</SPAN></A></P>
<P>迄今为止,我介绍的所有技术都用 XML 文档的形式生成服务器响应。但是,XML 有一些问题。其中一个就是延迟。浏览器不能立即解析
XML 文档并生成 DOM 模型,所以这会降低某些 Ajax
组件需要的“迅捷”感,特别是在较慢的机器上解析大型文档的时候更是如此。“现场搜索”就是一个示例,在这种搜索中,当用户输入搜索术语时,就会从服务器提取搜索结果并显示给用户。对于现场搜索组件来说,迅速地响应输入是非常重要的,但是同时它还需要迅速而持续地解析服务器的响应。</P>
<P>延迟是一个重要的考虑因素,但是避免使用 XML 的最大原因是差劲的客户端 DOM API。清单 5
显示了使用跨浏览器兼容的方式通过 DOM 得到某个值的时候,通常不得不面对的困难。</P><BR><BR><A
name=code5><B>清单 5. 在 JavaScript 中导航 XML 响应文档</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
// Find name of first item in customer's last order
var orderHistoryDoc = req.responseXML;
var orders = orderHistoryDoc.getElementsByTagName("order");
var lastOrder = orders[orders.length - 1];
var firstItem = lastOrder.getElementsByTagName("item")[0];
var itemNameElement = firstItem.firstChild;
var itemNameText = itemNameElement.firstChild.data;
</PRE></TD></TR></TBODY></TABLE><BR>
<P>当元素中间存在空白时,情况就变得更加复杂,因为每个元素的 <CODE>firstChild</CODE>
经常是个空白文本节点。现在有 JavaScript 库可以缓解处理 XML 文档的麻烦。这些库包括 Sarissa (请参阅 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax2/#resources">参考资料</A>)和
Google-ajaXSLT,这两个库都把 XPath 功能添加到了大多数浏览器中。</P>
<P>但是,想想替代方案还是值得的。除了 <CODE>responseXML</CODE>
之外,<CODE>XMLHttpRequest</CODE> 对象还提供了名为 <CODE>responseText</CODE>
的属性,这个属性只是以字符串的方式提供服务器的响应体。</P>
<P><A name=N101D8><SPAN class=smalltitle>responseText
属性</SPAN></A></P>
<P>当服务器需要向客户机发送非常简单的值时,<CODE>responseText</CODE> 特别方便,它可以避免 XML
导致的带宽支出和处理支出。例如,简单的 true/false
响应可以由服务器以纯文本方式返回,可以是逗号分隔的简单的名称或数字列表。但是,一般来说,最好不要在同一个应用程序中把 XML
响应和纯文本响应混合使用;保持单一数据格式可以让代码抽象和重用更加简单。</P>
<P><CODE>responseText</CODE> 与 XML
响应数据结合时也会有用。在只需要从响应文档中提取单一值的场景中,“欺骗性”地把 XML
当作文本字符串,而不把它当作结构化的文档对待,会更方便。例如,清单 6
显示了如何用正则表达式从顾客的订单历史中提取第一笔订单的日期。不过,这实际是种花招,一般不应当依赖 XML
文档的词汇表达。</P><BR><BR><A name=code6><B>清单 6. 用正则表达式处理 XMLHttpRequest 的
responseText 对象</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
var orderHistoryText = req.responseText;
var matches = orderHistoryText.match(/<date>(.*?)<\/date>/);
var date = matches[1];
</PRE></TD></TR></TBODY></TABLE><BR>
<P>在某些情况下,采用即时方式使用 <CODE>responseText</CODE>
会比较方便。但是,理想情况下,应当有种途径,可以用一种能够让 JavaScript 轻松导航、却没有 XML
处理支出的格式表示复杂的结构化数据。幸运的是,确实存在这样一种格式。</P><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=""
src="面向 Java 开发人员的 Ajax Ajax 的 Java 对象序列化.files/blue_rule.gif"
width="100%"><BR><IMG height=6 alt=""
src="面向 Java 开发人员的 Ajax 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 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 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-ajax2/#main"><B>回页首</B></A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><BR>
<P><A name=N101FC><SPAN class=atitle>JavaScript 对象标注</SPAN></A></P>
<P>实际上,JavaScript 对象的大部分都由联合数组、数字索引数组、字符串、数字或者这些类型的嵌套组合而成。因为所有类型都可以用
JavaScript 直接声明,所以可以在一条语句中静态地定义对象图。清单 7 使用 JSON
语法声明了一个对象,并演示了如何访问这个对象。大括号表示联合数组(即对象),它的键
-值组合由逗号分隔。方括号表示数字索引数组。</P><BR><BR><A name=code7><B>清单 7. 用 JSON 在
JavaScript 中直接声明一个简单对象</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
var band = {
name: "The Beatles",
members: [
{
name: "John",
instruments: ["Vocals","Guitar","Piano"]
},
{
name: "Paul",
instruments: ["Vocals","Bass","Piano","Guitar"]
},
{
name: "George",
instruments: ["Guitar","Vocals"]
},
{
name: "Ringo",
instruments: ["Drums","Vocals"]
}
]
};
// Interrogate the band object
var musician = band.members[3];
alert( musician.name
+ " played " + musician.instruments[0]
+ " with " + band.name );
</PRE></TD></TR></TBODY></TABLE><BR>
<P>既然 JSON 是一个有趣的语言特性,那么它对 Ajax 有什么意义呢?妙处在于可以用 JSON 在 Ajax
服务器响应中通过网络发送 JavaScript 对象图。这意味着在客户端可以避免使用笨拙的 DOM API 对 XML 进行导航 ——
只需要分析 JSON 响应,就会立即得到可以访问的 JavaScript 对象图。但是,首先需要把 JavaBean 变成
JSON。</P>
<P><A name=N10211><SPAN class=smalltitle>从 Java 类产生
JSON</SPAN></A></P>
<P>不同 XML 生成技术所具有的优缺点也适用于 JSON 的产生。而且可以证明,存在需要再次使用表示模板技术的情况。但是,使用
JSON 在理念上更接近于在应用层之间传递序列化的对象,而不是创建应用程序状态的视图。我将介绍如何用
<CODE>org.json</CODE> 这个 Java API 在 Java 类上创建
<CODE>toJSONObject()</CODE> 方法。然后,就可以把 <CODE>JSONObject</CODE>
简单地序列化成 JSON。清单 8 反映了 <A
href="http://www.ibm.com/developerworks/cn/java/j-ajax2/#code1">清单
1</A> 讨论的 XML,显示了 <CODE>Order</CODE> 类的 <CODE>toJSONObject()</CODE>
实现。</P><BR><BR><A name=code8><B>清单 8. Order 类的 toJSONObject()
方法实现</B></A><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=code-outline><PRE class=displaycode>
public JSONObject toJSONObject() {
JSONObject json = new JSONObject();
json.put("id",id);
json.put("cost",getFormattedCost());
json.put("date",date);
JSONArray jsonItems = new JSONArray();
for (Iterator<Item> iter =
items.iterator() ; iter.hasNext() ; ) {
jsonItems.put(iter.next().toJSONObject());
}
json.put("items",jsonItems);
return json;
}
</PRE></TD></TR></TBODY></TABLE><BR>
<P>可以看到,<CODE>org.json</CODE> API 非常简单。 <CODE>JSONObject</CODE> 代表
JavaScript 对象(即联
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -