对于 清单 5 中的 skeleton,其存根代码类似于 清单 6。
清单 6.存根代码
public class PurchaseOrderStub {
public void submitPurchaseOrder(
PurchaseOrderDocument doc) throws Exception {
SOAPEnvelope envelope = factory.getDefaultEnvelope();
XMLStreamReader reader = doc.newXMLStreamReader();
StAXOMBuilder builder = new StAXOMBuilder(reader);
OMElement payload= builder.getDocumentElement();
envelope.getBody().addChild(payload);
// ...
}
}
主要看看这几行:
XMLStreamReader reader = doc.newXMLStreamReader();
StAXOMBuilder builder = new StAXOMBuilder(reader);
Element payload= builder.getDocumentElement();
从这段代码可以看出,经过 StAX API 从对象到 AXIOM,与从 XML 到 AXIOM 没有什么区别。
但是初看起来不那么明显的是延迟构造仍然在起作用!即使在将载荷插入 SOAP 信封的过程中创建了 OMElement,内存中也没有重复的信息项。这是由于延迟构造和 AXIOM 内的多路技术造成的,它将从一个 API 输入的数据直接转发给另一个 API 输出。当消息最终写入流的时候,XMLBeans 提供的 XMLStreamReader 直接连接到传输 writer,后者将消息写入套接字 —— 假设此过程中没有要查看消息的处理程序。这意味着直到此时,数据仍然存放在 XMLBeans 对象中,真是好极了!
AXIOM 和数据绑定
这里讨论 AXIOM 的 SAX API,因为有些数据绑定框架不能使用其他的 API,比如 JAXB。虽然上述情况下使用 SAX 显然不会达到最佳性能,但从 AXIOM 到对象使用 SAX 并没有造成性能损失,因为这一步在任何情况下都是必需的。
如果使用 JAXB,那么存根程序就要使用 SAXOMBuilder 从数据绑定对象建立 AXIOM。清单 7 示范了这个过程。
清单 7. AXIOM 和 JAXB
public class PurchaseOrderStub {
public void submitPurchaseOrder(
PurchaseOrder doc) throws Exception {
SOAPEnvelope envelope = factory.getDefaultEnvelope();
SAXOMBuilder builder = new SAXOMBuilder();
JAXBContext jaxbContext = JAXBContext.newInstance("po");
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(doc, builder);
OMElement payload= builder.getDocumentElement();
envelope.getBody().addChild(payload);
//...
}
}
到目前为止,AXIOM 还不允许使用 OMElement 注册内容处理程序来处理收到的 SAX 事件。不过很容易编写一段胶水代码,从提供的 StAX 接口接收事件并驱动 SAX ContentHandler。有兴趣的读者可以从 参考资料 中的 JAXB 参考实现中找到这样的实现。
结束语
我介绍了与典型的 XML 对象模型相比 AXIOM 引入的一些很有前途的特性。注意本文仅仅介绍了部分特性。AXIOM 有很多更强大的特性,建议您从 Axis 2 源代码库下载最新的源代码,进一步研究 AXIOM。
