近在使用AXIS2部署Web Service,关于如果使用axis2部署Web Service的方法不想在这里多说,网站有很多相关的文章,这里只想谈谈AXIOM对象与Java中的对象的转换方法。
关于AXIOM的介绍,下面这个片段已经说得很明白了:
AXIs 对象模型 (AXIOM) 是一个 XML 对象模型,设计用于提高 XML 处理期间的内存使用率和性能,基于 Pull 解析。通过使用 Streaming API for XML (StAX) Pull 解析器,AXIOM(也称为 OM)可以控制解析过程,以提供延迟构建支持。延迟构建是指 AXIOM 不完全构建对象模型,模型的其余部分基于用户的需求构建。以下示例对此概念进行了说明:
假定某个用户需要从 XML 输入流中获得第一个人的 <Location>
元素值,AXIOM 构建的对象模型将一直包含到 <Location>
元素结束的内容,而让其他内容保留在流中:
<Persons> <Person> <Name>Dihini Himahansi</Name> <Sex>Female</Sex> <Location>Colombo, Sri Lanka</Location> <--- Object model is being built only up to this point </Person> <Person> <Name>Thushari Damayanthi</Name> <Sex>Female</Sex> <Location>Elpitiya, Sri Lanka</Location> </Person> </Persons> |
这里的优势在于,尽可能仅使用能满足用户的需求的内存。如果用户希望访问较大的文档中前面的数个字节或数千字节,则延迟构建功能将改善该应用程序的内存需求情况。
可以从任何元素获得 StAX 事件,而不管是否完整构建了对象模型。在有些情况下,Axis 2 中的此功能非常有用。例如,当 Axis2 作为中介传递时,如果需要仅读取 SOAP 消息的 Header,AXIOM 将防止其读取整个 SOAP 消息,使其具有很高的内存效率。另一个例子是,当 Web 服务实现能够直接使用 StAX 事件时,由于采用了 AXIOM,Web 服务所需的内存非常小。
此外,AXIOM 内置了消息传输优化机制(Message Transfer Optimization Mechanism,MTOM)支持。对于 AXIOM 体系结构,可以通过实现 AXIOM 接口并将其插入到 Axis2 中来执行自己的对象模型。
由于 AXIOM 最初是作为 Axis2 的对象模型而开发的,因此 AXIOM 提供了构建于基础 AXIOM API 之上的 SOAP 接口。这允许您使用envelope.getHeaders
和 envelope.getBody
之类的便利方法查看 SOAP。
AXIS2会将Web Service方法中的参数或返回值中的自定义对象、数组、List等类型统一映射为OMElement类型,这就我们需要编写OMElement与自定义类型质检的转换方法,下面给出几个常用的方法:
CASE1:自定义对象生成OMElement方法:
Person man = new Person();
man.setName("Warlaze");
man.setAge(25);
man.setAddress("Bei jing");
man.setPhonenum("13900000000");
javax.xml.stream.XMLStreamReader reader = BeanUtil.getPullParser(man);
StreamWrapper parser = new StreamWrapper(reader);
StAXOMBuilder stAXOMBuilder =OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory.getOMFactory(), parser);
OMElement element = stAXOMBuilder.getDocumentElement();
CASE2:List或Array类型生成OMElement方法:
List<Person> list = new ArrayList<Person>();
list.add(man);
list.add(man);
OMElement omElement = BeanUtil.getOMElement(new QName("root"), list
.toArray(), new QName("person"), false, null);
CASE3:解析包含基本类型的List或Array生成的OMElement的方法:
private static List<String> getResults(OMElement element) {
if(element == null){
return null;
}
Iterator iterator = element.getChildElements();
List<String> list = new ArrayList<String>();
while (iterator.hasNext()) {
OMNode omNode = (OMNode) iterator.next();
if (omNode.getType() == OMNode.ELEMENT_NODE) {
OMElement omElement = (OMElement) omNode;
if (omElement.getLocalName().equals("string")) {
String temp = omElement.getText().trim();
System.out.println(temp);
list.add(temp);
}
}
}
return list;
}
CASE4:解析包含自定义Java类型的List或Array的方法:
private static List<Person> getResults(OMElement element) throws AxisFault {
if (element == null) {
return null;
}
Iterator iterator = element.getChildElements();
List<Person> list = new ArrayList<Person>();
while (iterator.hasNext()) {
OMNode omNode = (OMNode) iterator.next();
if (omNode.getType() == OMNode.ELEMENT_NODE) {
OMElement omElement = (OMElement) omNode;
if (omElement.getLocalName().toLowerCase().equals("person")) {
Person person = (Person) BeanUtil.processObject(omElement,
Person.class, null, true,
new DefaultObjectSupplier());
list.add(person);
}
}
}
return list;
}
ps:
在现在项目中使用axis2,发现其源码有一个问题:
在org.apache.axis2.databinding.utils.BeanUtil.java-500 line
String partsLocalName = parts.getLocalName();
PropertyDescriptor prty = (PropertyDescriptor)properties.get(
partsLocalName.toLowerCase());
if (prty != null) {...
可以看到,在第500行进行了一个toLowerCase()转换,导致自定义类型的转换出现bean属性丢失,
将它去掉,重新打包就可以正常运行了;
不明白为什么axis2工作小组要进行这样处理呢;
不知道这算不算一个bug,总不能就规定我们只能使用全部小写字母来定义bean属性吧,有违java编码规范啊;
看来要给apache反应一下