1. 程式人生 > >JDK中JAXB常用註解

JDK中JAXB常用註解

  • @XmlRootElement

@Retention(RUNTIME)
@Target({TYPE})//作用在類上
public @interface XmlRootElement {
    //指定生成的元素所屬的名稱空間
    String namespace() default "##default";
    //指定生成元素的名字,若不指定則預設使用類名小寫作為元素名
    String name() default "##default";
}

類級別的註解,將類對映為xml全域性元素,也就是根元素。就像spring配置檔案中的beans。常與@XmlType,@XmlAccessorType,@XmlAccessorOrder連用。

主意:如果屬性欄位是Null,也就是沒有給屬性設定值,那麼JDK自帶的JXABContext將JavaBean轉成XML字串時,是沒有該屬性欄位的節點的。

  • @XmlElement

@Retention(RUNTIME) @Target({FIELD, METHOD, PARAMETER})
public @interface XmlElement {
   //指定生成元素的名字
    String name() default "##default";
   //指定元素的文字值是否可以為空,預設為false。
    boolean nillable() default false;
   //指定該元素是否必須出現,預設為false
    boolean required() default false;
   //指定該元素所屬的名稱空間
    String namespace() default "##default";
   //指定該元素預設的文字值
    String defaultValue() default "\u0000";
}

欄位,方法,引數級別的註解。該註解可以將被註解的欄位(非靜態)對映為本地元素,也就是子元素。預設使用欄位名。常與@XmlValue,@XmlJavaTypeAdapter,@XmlElementWrapper連用。 注意: 如果註解加在set方法上,是沒問題的。 但是如果要加在filed欄位上,那麼需要與@XmlAccessorType(XmlAccessType.FIELD)一起使用,否則會報錯(任何註解如果要加在欄位上都需要這樣)。

  • @XmlAttribute

 @Retention(RUNTIME) @Target({FIELD, METHOD})
 public @interface XmlAttribute {
   //屬性名
    String name() default "##default";
   //屬性是否必需
    boolean required() default false;
   //名稱空間
    String namespace() default "##default" ;
}

欄位和方法級別的註解。該註解會將欄位對映成本類對應元素的屬性,屬性名預設使用欄位名。

  • @XmlTransient

@Retention(RUNTIME) @Target({FIELD, METHOD, TYPE})
public @interface XmlTransient {}

類,欄位,方法級別的註解。可使JAXB在對映xml元素時忽略被註解的類,欄位,get/set對應欄位。需要注意的是該註解與所有其他JAXB註釋相互排斥,也就是說與其他註釋連用就會報錯。該註解沒有屬性。

  • @XmlAccessorType

@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE})
public @interface XmlAccessorType {
   //可取的值是一個名為XmlAccessType的列舉型別裡的值
    XmlAccessType value() default XmlAccessType.PUBLIC_MEMBER;
}

包和類級別的註解。javaEE的API對該註解的解釋是:控制欄位是否被預設序列化。通俗來講,就是決定哪些欄位或哪些get/set方法對應的欄位會被對映為xml元素,需要注意的是欄位或get/set方法的訪問許可權(public/private)會影響欄位是否被對映為xml元素。

XmlAccessType的列舉型別包括:

  • XmlAccessType.PROPERTY 1.當使用了該值,只要欄位有對應的get/set方法對(注意是成對出現,只有其中一個不會發生對映),不需要使用@XmlElement註解,不論該方法的訪問許可權是什麼(即使是private),jaxb就會將該欄位對映成xml元素。不過最好加上@XmlElement註解,get/set方法任選一個即可,都加上會報錯。 2.若在一個欄位有set/get方法對但又在欄位上新增@XmlElement註解會報屬性重複的錯誤。 3.若沒有set/get方法對,則需要在欄位上使用@XmlElement註解才可以對映為xml元素,否則不會發生對映。 4.若get/set方法上使用了@XmlTransient註解,但想要對應欄位發生對映,需要在對應欄位上新增@XmlElement註解,此時不會報錯,並將該欄位對映為xml元素。

  • XmlAccessType.FIELD(一般就是這個) 1.每個非靜態的欄位(無論訪問許可權如何)都會被jaxb對映為xml元素,即使沒有get/set方法對,即使沒有使用@XmlElement元素,但最好加上該註解以表明該欄位要被對映為xml元素。 2.雖然沒有get/set方法對,也會發生對映,但加上get/set方法對也不會報錯,因為我們經常會使用這兩個方法。但注意,不能再在這兩個方法上使用@XmlElement方法,否則會報屬性重複的錯誤。 3.若在欄位上使用了@XmlTransient註解,但還想讓該欄位發生對映,需要在該欄位對應的get/set方法上新增@XmlElement

  • XmlAccessType.PUBLIC_MEMBER (該值為預設值) 1.每個訪問許可權為public的欄位,或者每個訪問許可權為public的get/set方法對,都會將欄位對映為xml元素,即使不使用@XmlElement,但最好加上。不可同時存在public欄位和對應的get/set方法對,不然會報屬性重複的錯誤。 2.若使用@XmlElement註解,需要注意只能在欄位或get/set方法新增,兩者任選其一,否則會報屬性重複的錯誤。 3.若欄位不為public,get/set方法為public並使用了@XmlTransient,需要在欄位上新增@XmlElement才會發生對映。 若欄位為public並使用了@XmlTransient,get/set方法對不為public,需要在get/set方法上使用@XmlElement才會對映。

  • XmlAccessType.NONE 任何欄位,get/set方法對都不會發生對映,除非使用某些註解。 如@XmlElement,@XmlElementWrapper等。

  • @XmlAccessorOrder

@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE})
public @interface XmlAccessorOrder {
        XmlAccessOrder value() default XmlAccessOrder.UNDEFINED;
}

包和類級別的註解。控制生成元素的順序。 只有一個value屬性,可取的值是一個名為XmlAccessOrder的列舉型別的兩個值: XmlAccessOrder.ALPHABETICAL :按照字母表的順序對生成的元素排序。 XmlAccessOrder.UNDEFINED(預設):按照類中欄位的順序生成元素的順序。

  • @XmlElementWrapper

 @Retention(RUNTIME) @Target({FIELD, METHOD})
 public @interface XmlElementWrapper {
   //包裝標籤名
    String name() default "##default";
   //包裝標籤名稱空間
    String namespace() default "##default";
   //指定元素的文字值是否可以為空,預設為false。
    boolean nillable() default false;
   //是否必需
    boolean required() default false;
}

欄位和方法級別的註解。圍繞被對映的xml元素生成包裝元素。主要用在集合物件對映後生成包裝對映結果的xml元素。 一般用在集合欄位上。

  • @XmlJavaTypeAdapter

@Retention(RUNTIME) @Target({PACKAGE,FIELD,METHOD,TYPE,PARAMETER})
public @interface XmlJavaTypeAdapter {
   //自定義的介面卡類.class
    Class<? extends XmlAdapter> value();

    Class type() default DEFAULT.class;

    static final class DEFAULT {}

}

包、類、欄位,方法、引數級別的註解。解決java日期(Date),數字(Number)格式化問題。 該註解的用法就是自定義介面卡並繼承XmlAdapter類,實現裡面的marshal和unmarshal方法,並在該註解上引用。

  • @XmlValue

@Retention(RUNTIME) @Target({FIELD, METHOD})
public @interface XmlValue {}

欄位和方法級別的註解。該註解的作用,簡單理解就是定義xml元素文字值的型別,例如在一個類的String型別欄位上使用該註解,則生成的元素文字值型別就是xsd:string,也就是定義一個xsd中的simpleType.若類中還有一個欄位並使用了@XmlAttribute註解,則是定義一個xsd中的complexType。

  • @XmlType

@Retention(RUNTIME) @Target({TYPE})
public @interface XmlType {

    String name() default "##default" ;

    String[] propOrder() default {""};

    String namespace() default "##default" ;

    Class factoryClass() default DEFAULT.class;

    static final class DEFAULT {}

    String factoryMethod() default "";
}

類級別的註解。該註解有些複雜,主要使用的是它的propOrder屬性,簡單來說是用來定義xsd中的simpleType或complexType,從生成的xml中來看,它的作用就是指定生成元素的順序,具體看下圖:

簡單解釋下每行什麼意思:

  • 若指定該註解的propOrder為{},會生成ComplexType並且使用xs:all指示器,表示所有被對映的元素都必須出現在xml中

  • 若propOrder的值為{“name”, “addr”, “area”}(大括號中都是Person類的欄位名稱),會生成ComplexType並使用xs:sequence指示器,表示生成的xml元素必須按照propOrder指定的順序出現,也就間接實現了排序。

  • 若不指定propOrder屬性(這與指定propOrder但值為{}不同),沒有欄位,會生成ComplexType幷包含一個空的xs:sequence指示器。

  • 若不指定propOrder屬性,但含有被@XmlValue註解的欄位和被@XmlAttribute註解的欄位,會生成一個含有simpleContent的ComplexType。

  • 若不指定propOrder屬性,但含有被@XmlValue註解的欄位而沒有被@XmlAttribute註解的欄位,會生成一個含有simpleType的ComplexType。