-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Jaxb
##Overview 参见Serialize总述
JAXB的非官方文档: http://jaxb.java.net/guide/
##SpringSide-Core中的JaxbMapper Jaxb中最讨厌的地方,是需要在构造JAXBContext时,预先设定可能会处理的Root Element Types。 Springside参考Spring里的做法,封装类一个静态的Map,为每一个Class维护了一个JaxbContext,这样子就仍然可以以静态函数的方式调用Mapper了。
第二麻烦就是处理顶级对象是个Collection,而不是POJO的场景。 JAXBMapper专门提供了如下的toXML函数,使用了一个注释了@XmlAnyElement的Wrapper来实现。
String toXml(Collection<?> root, String rootName)
另外JAXBContext是线程安全的可任意重用。Marshaller和Unmarshaller则是线程不安全的,需要每次创建。如果性能很苛刻,可以对Unmarshaller对象进行Pooling,保证每次只被一条线程调用,但使用后不会销毁而是放回池里。
##SpringSide showcase中的JaxbDemo
Jaxb目录下的User对象演示了几种典型的Jaxb Annotation, 包括@XmlAttribute, @XmlTransient, @XmlType(propOrder = {...})
还有另一个常用的配置是将Collection属性输出成大家一般期望的样子。 比如:
@XmlElementWrapper
@XmlElement(name = "role")
public List<Role> getRoles() {
return roles;
}
必须要这样以后, 输出才是大家一般期望样子,这是JAXB第三个傻的地方。
<roles><role id="1" name="admin"/></roles>
最后,还演示了Map<String,String>序列化到下面的样子,这是最高境界了,使用了@XmlJavaTypeAdapter 和 一个自己写的HouseMapAdapter。这么复杂的情况,再让我写一次出来都不一定能行。 建议还是懒一点,按默认输出,难看就难看一点了。
<houses>
<house key="bj">house1</item>
<hosue key="gz">house2</item>
</houses>
默认输出是这样子的:
<map>
<entry>
<key>a</key>
<value>1</value>
</entry>
<entry>
<key>b</key>
<value>2</value>
</entry>
</map>
##文档里的有用Tips
- Mapping interfaces: http://jaxb.java.net/guide/Mapping_interfaces.html
- Mappting 循环依赖: http://jaxb.java.net/guide/Mapping_cyclic_references_to_XML.html
- 处理大文件: http://jaxb.java.net/guide/Dealing_with_large_documents.html