Jaxb

优质
小牛编辑
130浏览
2023-12-01

Overview

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序列化到下面的样子,这是最高境界了,使用了@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