美文网首页
JAXB的@XmlAccessorType和@XmlTransi

JAXB的@XmlAccessorType和@XmlTransi

作者: JohnShen | 来源:发表于2016-01-14 16:02 被阅读3777次

    原文地址:[https://jaxb.java.net/tutorial/section_6_2_5-Controlling-Element-Selection-XmlAccessorType-XmlTransient.html#Controlling Element Selection: XmlAccessorType, XmlTransient](https://jaxb.java.net/tutorial/section_6_2_5-Controlling-Element-Selection-XmlAccessorType-XmlTransient.html#Controlling Element Selection: XmlAccessorType, XmlTransient)

    如果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注解来禁止绑定。

    相关文章

      网友评论

          本文标题:JAXB的@XmlAccessorType和@XmlTransi

          本文链接:https://www.haomeiwen.com/subject/tdfhkttx.html