扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
如何用 Java servlet 处理和响应请求(向客户机返回 XML 文档)。
如何在客户端用响应文档更新页面视图。
这一次,我将继续讨论 Ajax 开发的基础知识,但是将侧重于许多 Java Web 开发人员最关心的问题:为客户机生成数据。
多数 Java 开发人员已经把模型-视图-控制器(MVC)模式应用在他们的 Web 应用程序上。在传统的 Web 应用程序中,视图组件由 JSP 或者其他表示技术(例如 Velocity 模板)构成。这些表示组件动态地生成全新的 HTML 页面,替代用户以前正在查看的页面,从而更新用户界面。但是,在 Java Web 应用程序使用 Ajax UI 的情况下,基于从 XMLHttpRequest 的响应接收到的数据,JavaScript 客户端代码对于更新用户看到的内容负有最终责任。从服务器的角度来看,视图成为它响应客户机请求而发送的数据表示。
这篇文章侧重于可以用来生成 Java 对象以数据为中心的视图的技术。我将演示可以把 JavaBeans 变成 XML 文档的各种方法,并且讨论每种方法的优劣。您将看到为什么 XML 并不总是最好的途径:对于简单的 Ajax 请求来说,传输纯文本更好。最后,我将介绍 JavaScript 对象标注(JSON)。JSON 允许数据以序列化的 JavaScript 对象图的形式传输,在客户端代码中处理序列化的 JavaScript 对象图极为容易。
关于示例
我将使用一个示例应用程序和几个用例来演示这里讨论的技术特性和技术。图 1 显示的极为简单的数据模型可以表示示例用例。这个模型代表在线商店中的顾客帐户。顾客拥有以前订单的集合,每个订单包含几个商品。
图 1. 简单的对象模型
虽然 XMLHttpRequest 对于发送数据使用的格式没有做任何限制,但是对于多数目的来说,只发送传统的表单数据是适合的,所以我的讨论集中在服务器的响应上。响应也可以有基于文本的格式,但是正如它的名字表示的,XMLHttpRequest 具有内置的处理 XML 响应数据的能力。这使 XML 成为 Ajax 响应的默认选择,所以我们从 XML 格式开始讨论。
从 Java 类产生 XML
把 Ajax 响应作为 XML 来传递有许多原因:每个支持 Ajax 的浏览器都有导航 XML 文档的方法,也有许多服务器端技术可以处理 XML 数据。通过制定一个方案,描述要交换的文档类型,在 Ajax 客户端和服务器端之间很容易定义合约,而且如果服务器端架构采用面向服务的方式,那么使用 XML 也可以允许非 Ajax 客户机使用您提供的数据。
我将考虑从 Java 对象产生 XML 数据的三种方法,并讨论每种方法的优劣。
自行进行序列化
首先,可以从对象图以编程的方式生成 XML。这种方式可以简单到只是在每个 JavaBean 类中实现 toXml() 方法即可。然后就可以选择合适的 XML API,让每个 bean 提供表示自己状态的元素,并递归地对自己的成员调用对象图。显然,这种方式无法扩展到大量的类,因为每个类都需要专门编写自己的 XML 生成代码。从好的方面来看,这是一个实现起来简单的方式,没有额外的配置支出或者更复杂的构建过程支出,任何 JavaBean 图都可以只用几个调用就变成 XML 文档。
在前一篇文章的示例代码中,我把 XML 标记字符串连接在一起,实现了 toXml() 方法。上次我就提到过,这是个糟糕的方法,因为它把确保标记配对、实体编码等工作的负担放在每个 toXml() 方法的代码中。在 Java 平台上有几个 XML API 可以替您做这些工作,这样您就可以把精力集中在 XML 的内容上。清单 1 用 JDOM API 实现了在线商店示例中表示订单的类中的 toXml()(请参阅 图 1)。
清单 1. Order 类的 toXml() 的 JDOM 实现
public Element toXml() {
Element elOrder = new Element("order");
elOrder.setAttribute("id",id);
elOrder.setAttribute("cost",getFormattedCost());
Element elDate = new Element("date").addContent(date);
elOrder.addContent(elDate);
Element elItems = new Element("items");
for (Iterator<Item> iter =
items.iterator() ; iter.hasNext() ; ) {
elItems.addContent(iter.next().toXml());
}
elOrder.addContent(elItems);
return elOrder;
}
在这里可以看到用 JDOM 创建元素、使用属性和添加元素内容有多么简单。递归地调用复合 JavaBean 的 toXml() 方法是为了取得它们子图的 Element 表示。例如,items 元素的内容是通过调用 Order 聚合的每个 Item 对象上的 toXml() 得到的。
一旦所有的 JavaBean 都实现了 toXml() 方法,那么把任意对象图序列化成 XML 文档并返回给 Ajax 客户机就简单了,如清单 2 所示。
清单 2. 从 JDOM 元素生成 XML 响应
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws java.io.IOException, ServletException {
String custId = req.getParameter("username");
Customer customer = getCustomer(custId);
Element responseElem = customer.toXml();
Document responseDoc = new Document(responseElem);
res.setContentType("application/xml");
new XMLOutputter().output(responseDoc,res.getWriter());
}
JDOM 再次把工作变得非常简单。只需要在对象图返回的 XML 元素外面包装一个 Document,然后用 XMLOutputter 把文档写入 servlet 响应即可。清单 3 显示了用这种方式生成的 XML 示例,用 JDOM Format.getPrettyFormat() 对 XMLOutputter 进行初始化,格式化得非常好。在这个示例中,顾客只做了一个订单,包含两个商品。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者