【Java】JABX實現對象與XML互轉


JABX簡介

  JAXB能夠使用Jackson對JAXB注解的支持實現(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,這樣一來可以更好的標志可以轉換為JSON對象的JAVA類。JAXB允許JAVA人員將JAVA類映射為XML表示方式,常用的注解包括:@XmlRootElement,@XmlElement等等。

  JAXB(Java Architecture for XML Binding) 是一個業界的標准,是一項可以根據XML Schema產生Java類的技術。該過程中,JAXB也提供了將XML實例文檔反向生成Java對象樹的方法,並能將Java對象樹的內容重新寫到XML實例文檔。從另一方面來講,JAXB提供了快速而簡便的方法將XML模式綁定到Java表示,從而使得Java開發者在Java應用程序中能方便地結合XML數據和處理函數。

JDK中JAXB相關的重要Class和Interface:

  JAXBContext類,是應用的入口,用於管理XML/Java綁定信息。
  Marshaller接口,將Java對象序列化為XML數據。
  Unmarshaller接口,將XML數據反序列化為Java對象。

JDK中JAXB相關的重要Annotation:

  @XmlType,將Java類或枚舉類型映射到XML模式類型
  @XmlAccessorType(XmlAccessType.FIELD) ,控制字段或屬性的序列化。FIELD表示JAXB將自動綁定Java類中的每個非靜態的(static)、非瞬態的(由@XmlTransient標注)字段到XML。其他值還有XmlAccessType.PROPERTY和XmlAccessType.NONE。
  @XmlAccessorOrder,控制JAXB 綁定類中屬性和字段的排序。
  @XmlJavaTypeAdapter,使用定制的適配器(即擴展抽象類XmlAdapter並覆蓋marshal()和unmarshal()方法),以序列化Java類為XML。
  @XmlElementWrapper ,對於數組或集合(即包含多個元素的成員變量),生成一個包裝該數組或集合的XML元素(稱為包裝器)。
  @XmlRootElement,將Java類或枚舉類型映射到XML元素。
  @XmlElement,將Java類的一個屬性映射到與屬性同名的一個XML元素。
  @XmlAttribute,將Java類的一個屬性映射到與屬性同名的一個XML屬性。

Marshaller接口和Unmarshaller接口

  下面舉例說明,將Java對象序列化為XML數據,以及將XML數據反序列化為Java對象

  • pojo對象
     1 package test.hd.pojo;
     2 
     3 
     4 import javax.xml.bind.annotation.XmlAccessType;
     5 import javax.xml.bind.annotation.XmlAccessorType;
     6 import javax.xml.bind.annotation.XmlRootElement;
     7 import javax.xml.bind.annotation.XmlType;
     8 
     9 
    10 @XmlRootElement
    11 @XmlAccessorType(XmlAccessType.FIELD)
    12 //控制JAXB 綁定類中屬性和字段的排序  
    13 @XmlType(propOrder = {   
    14      "age",   
    15      "name" 
    16 })  
    17 public class Person {
    18 
    19     private String name;
    20     
    21     private Integer age;
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public void setName(String name) {
    28         this.name = name;
    29     }
    30 
    31     public Integer getAge() {
    32         return age;
    33     }
    34 
    35     public void setAge(Integer age) {
    36         this.age = age;
    37     }
    38     
    39 }

     

      
  • 測試類 
     1 package test.hd.test_jaxb;
     2 
     3 import java.io.IOException;
     4 import java.io.StringReader;
     5 import java.io.Writer;
     6 
     7 import javax.xml.bind.JAXBContext;
     8 import javax.xml.bind.JAXBException;
     9 import javax.xml.bind.Marshaller;
    10 import javax.xml.bind.Unmarshaller;
    11 
    12 import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;
    13 
    14 import test.hd.pojo.Person;
    15 
    16 public class Test {
    17 
    18     public static void main(String[] args) throws JAXBException {
    19 
    20         marshall();//對象轉xml
    21         unMarshal();//xml轉對象
    22     }
    23 
    24     /**
    25      * 對象轉xml
    26      * 
    27      * @throws JAXBException
    28      */
    29     public static void marshall() throws JAXBException {
    30         Person person = new Person();
    31         person.setName("H__D");
    32         person.setAge(11);
    33 
    34         JAXBContext context = JAXBContext.newInstance(Person.class);
    35         Marshaller marshaller = context.createMarshaller();
    36         marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    37         // xml格式
    38         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    39         // 去掉生成xml的默認報文頭
    40         // marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
    41         // 不進行轉義字符的處理
    42         marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CharacterEscapeHandler() {
    43             public void escape(char[] ch, int start, int length, boolean isAttVal, Writer writer) throws IOException {
    44                 writer.write(ch, start, length);
    45             }
    46         });
    47         // 將XML打印到控制台
    48         marshaller.marshal(person, System.out);
    49 
    50     }
    51 
    52     /**
    53      * xml轉對象
    54      * 
    55      * @throws JAXBException
    56      */
    57     public static void unMarshal() throws JAXBException {
    58 
    59         JAXBContext context = JAXBContext.newInstance(Person.class);
    60         Unmarshaller unmarshaller = context.createUnmarshaller();
    61 
    62         Person p = (Person) unmarshaller.unmarshal(new StringReader("<person><name><![CDATA[H__D]]></name><age>11</age></person>"));
    63 
    64         System.out.println("person = " + p.getName() + "------" + p.getAge());
    65     }
    66 
    67 }

     

  • 控制台輸出


    JABX注解使用

  • @XmlType 定義映射的一些相關規則
    參數:
     propOrder        指定映射XML時的節點順序
     factoryClass     指定UnMarshal時生成映射類實例所需的工廠類,默認為這個類本身
     factoryMethod  指定工廠類的工廠方法
     name               定義XML Schema中type的名稱
     namespace      指定Schema中的命名空間

  • @XmlAccessorType  定義映射這個類中的何種類型需要映射到XML。可接收四個參數,分別是:

     XmlAccessType.FIELD:映射這個類中的所有字段到XML
     XmlAccessType.PROPERTY:映射這個類中的屬性(get/set方法)到XML
     XmlAccessType.PUBLIC_MEMBER:將這個類中的所有public的field或property同時映射到XML(默認)
     XmlAccessType.NONE:不映射

  •  @XmlAccessorOrder用於對java對象生成的xml元素進行排序。它有兩個屬性值:

         XmlAccessorOrder.ALPHABETICAL:對生成的xml元素按字母順序排序;
         XmlAccessorOrder.UNDEFINED:不排序。

  • @XmlJavaTypeAdapter常用在轉換比較復雜的對象時,如map類型或者格式化日期等。使用此注解時,需要自己寫一個adapter類繼承XmlAdapter抽象類,並實現里面的方法。@XmlJavaTypeAdapter(value=xxx.class),value為自己定義的adapter類

    XmlAdapter如下:
     @XmlElementWrapper注解表示生成一個包裝 XML 表示形式的包裝器元素。 此元素主要用於生成一個包裝集合的包裝器 XML 元素。

     例如需要輸出CDATA格式的數據時,編寫一個CDataAdapter類,然后使用XmlJavaTypeAdapter注解:

     1 package test.hd.util;
     2 
     3 import javax.xml.bind.annotation.adapters.XmlAdapter;
     4 
     5 /**
     6  * 有時候 Java 類不能自然映射到自己所需的 XML 形式,
     7  * 這時需要編寫自己的適配器類,通過注解綁定到javabean的成員變量上,
     8  * 在運行的時候jaxb框架自動會適配你所編寫的適配器類的方法,
     9  * CDataAdapter.marshal(String str),將javabean的成員變量的value值
    10  * 轉變成你想要的形式。
    11  * @author H__D
    12  * @date 2017年6月19日 下午4:32:00
    13  *
    14  */
    15 public class CDataAdapter extends XmlAdapter<String, String> {
    16 
    17     // 從javabean到xml的適配方法
    18     @Override
    19     public String marshal(String str) throws Exception {
    20         return "<![CDATA[" + str + "]]>";
    21     }
    22 
    23     // 從xml到javabean的適配方法
    24     @Override
    25     public String unmarshal(String str) throws Exception {
    26         return str;
    27     }
    28 
    29 }
     1 package test.hd.pojo;
     2 
     3 import java.io.Serializable;
     4 
     5 import javax.xml.bind.annotation.XmlAccessOrder;
     6 import javax.xml.bind.annotation.XmlAccessType;
     7 import javax.xml.bind.annotation.XmlAccessorOrder;
     8 import javax.xml.bind.annotation.XmlAccessorType;
     9 import javax.xml.bind.annotation.XmlRootElement;
    10 import javax.xml.bind.annotation.XmlType;
    11 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    12 
    13 import test.hd.util.CDataAdapter;
    14 
    15 @XmlRootElement
    16 @XmlAccessorType(XmlAccessType.FIELD)
    17 //控制JAXB 綁定類中屬性和字段的排序  
    18 @XmlType(propOrder = {   
    19      "age",   
    20      "name" 
    21 })  
    22 @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
    23 public class Person {
    24 
    25     @XmlJavaTypeAdapter(CDataAdapter.class)
    26     private String name;
    27     
    28     private Integer age;
    29 
    30     public String getName() {
    31         return name;
    32     }
    33 
    34     public void setName(String name) {
    35         this.name = name;
    36     }
    37 
    38     public Integer getAge() {
    39         return age;
    40     }
    41 
    42     public void setAge(Integer age) {
    43         this.age = age;
    44     }
    45     
    46     
    47     
    48 }

    輸出如下


  • @XmlElementWrapper  為數組元素或集合元素定義一個父節點。如,類中有一元素為List items,若不加此注解,該元素將被映射為

        <items>...</items>
        <items>...</items>

    這種形式,此注解可將這個元素進行包裝,如:

        @XmlElementWrapper(name="items")
        @XmlElement(name="item")
        public List items;

    將會生成這樣的XML樣式:

        <items>
            <item>...</item>
            <item>...</item>
        </items>

  • @XmlRootElement   將一個Java類映射為一段XML的根節點

    參數:
     name            定義這個根節點的名稱
     namespace   定義這個根節點命名空間

  • @XmlElement  指定一個字段或get/set方法映射到XML的節點。如,當一個類的XmlAccessorType 被標注為PROPERTY時,在某一個沒有get/set方法的字段上標注此注解,即可將該字段映射到XML。
    參數:
             defaultValue 指定節點默認值
             name  指定節點名稱
             namespace     指定節點命名空間
             required 是否必須(默認為false)
             nillable 該字段是否包含 nillable="true" 屬性(默認為false)
             type  定義該字段或屬性的關聯類型

  • @XmlAttribute  指定一個字段或get/set方法映射到XML的屬性。
    參數:
     name  指定屬性名稱
     namespace     指定屬性命名空間
     required 是否必須(默認為false)

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM