JAXB的@XmlAccessorType和@XmlTransient

来源:互联网 发布:高新区行知小学 重点 编辑:程序博客网 时间:2024/05/16 00:47

如果JAXB将一个类绑定到了XML,那么默认地,所有的public成员将会被绑定。比如,公共的getter和setter方法对,或者公共的field。任何protected,package-visible或者private的成员都会被绑定,如果它被添加了一个合适的注解,比如@XmlElement或者@XmlAttribute。你有若干的可能性来影响它的默认行为。

你可以将一个package或者一个顶层的class用@XmlAccessorType来注解,然后设置它的value元素的值为枚举常量中的其中一个(FIELD,PROPERTY, PUBLIC_MEMBER, NONE)。如果FIELD被设置,那么每一个非static和非transient的field将会被自动地绑定。设置为PROPERTY可以告诉JAXB去为getter和setter方法对做数据绑定。NONE的设置会禁止绑定,除了对那些已经被明确注解的field或property。一个没有使用这个注解的类将会从它的父类或者package设置中继承。

另一个在这个上下文中被提及的注解是@XmlTransient。它会为它的target阻止绑定操作,这个target可以是一个class或者一个field或者一个method。如果你遇到了从public field导致的名字冲突(拿foo来说,getFoo和setFoo),那么使用@XmlTransient将会是很有用的。

第一个class将访问类型设置为PUBLIC_MEMBER来限制一组XML元素。成员getB在绑定的时候将会被锁定。

@XmlAccessorType( XmlAccessType.PUBLIC_MEMBER )public class SomeClass {    private String a;    private String b;    public SomeClass(){ ... }    public String getA(){ ... }    public void setA( String value ){ ... }    @XmlTransient    public String getB(){ ... }    public void setB( String value ){ ... }}

与其对应的XML schema类型定义将会像下面这样:

<xs:complexType name="someClass">    <xs:sequence>    <xs:element name="a" type="xs:string" minOccurs="0"/>    </xs:sequence></xs:complexType>

第二个例子展示了反向的过程。它展示了一个被设置为最高限制访问类型的class,这个class有一个成员被明确注解成为一个element。

@XmlAccessorType( XmlAccessType.NONE )public class OtherClass {    private String a;    private String b;    public OtherClass(){ ... }    public String getA(){ ... }    public void setA( String value ){ ... }    @XmlElement( required = true )    public String getB(){ ... }    public void setB( String value ){ ... }}

由于我们已经将element的注解设置为true,那么生成的schema片段就将会有一点点不同:

<xs:complexType name="otherClass">    <xs:sequence>        <xs:element name="b" type="xs:string"/>    </xs:sequence></xs:complexType>

最后这个例子展示了使用这些注解在一些特殊的情况下。首先,@XmlTransient被用在public field上来避免方法对的名字冲突。其次,@XmlElement被用来为getB请求绑定,而它并没有自己的setB配偶。(getter方法遵循JAXB为elements绑定到List<?>所生成Java代码的标准模式,在list对象上有一些改变)

@XmlAccessorType( XmlAccessType.PUBLIC_MEMBER )public class SpecialClass {    @XmlTransient    public String a;    private List<String> b;    public SpecialClass(){ ... }    public String getA(){ ... }    public void setA( String value ){ ... }    @XmlElement    public List<String> getB(){        if( b == null ) b = new ArrayList<String>();        return b;    }}

生成的复合类型会将两个element都包含在内。

<xs:complexType name="specialClass">    <xs:sequence>        <xs:element name="a" type="xs:string" minOccurs="0"/>        <xs:element name="b" type="xs:string" maxOccurs="unbounded" minOccurs="0"/>    </xs:sequence></xs:complexType>

总的来看,你可以通过在package级别设置,给在一个包中的所有class指定策略;或者通过在class级别设置,给它所有的子类指定策略。这个策略可以在field或者property上,并且是很宽松的。也可以是很严格地默认什么也不允许。在这个class中,你可以通过添加@XmlElement或者@XmlAttribute来扩展一个限制严格的设置。或者你可以使用@XmlTransient注解来禁止绑定。

原创粉丝点击