JAXB注解 java 关于xml的注解,自动生成xml文件 - @XML***

时间:2020-11-25 11:54:40

java和xml的互相转换,依靠强大的JAXBContext可以轻松实现。

下面通过一个简单案例学习一下JAXBContext


首先准备好一个JavaBean供实验:

注意

1、类文件注解:@XmlRootElement不可缺少

2、2个Student的构造方法不能少

  1. @XmlRootElement  
  2. public class Student {  
  3.     private String name;  
  4.     private String width;  
  5.     private String height;  
  6.     private int age;  
  7.       
  8.       
  9.     public Student(String name, String width, String height, int age) {  
  10.         super();  
  11.         this.name = name;  
  12.         this.width = width;  
  13.         this.height = height;  
  14.         this.age = age;  
  15.     }  
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.     public void setName(String name) {  
  20.         this.name = name;  
  21.     }  
  22.     public String getWidth() {  
  23.         return width;  
  24.     }  
  25.     public void setWidth(String width) {  
  26.         this.width = width;  
  27.     }  
  28.     public String getHeight() {  
  29.         return height;  
  30.     }  
  31.     public void setHeight(String height) {  
  32.         this.height = height;  
  33.     }  
  34.     public int getAge() {  
  35.         return age;  
  36.     }  
  37.     public void setAge(int age) {  
  38.         this.age = age;  
  39.     }  
  40.     public Student() {  
  41.         super();  
  42.     }  
  43.       
  44. }  
@XmlRootElement
public class Student {
private String name;
private String width;
private String height;
private int age;


public Student(String name, String width, String height, int age) {
super();
this.name = name;
this.width = width;
this.height = height;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
super();
}

}


JavaToXml:

  1. @Test  
  2. public void test01(){  
  3.     try {  
  4.         JAXBContext jc = JAXBContext.newInstance(Student.class);  
  5.         Marshaller ms = jc.createMarshaller();  
  6.         Student st = new Student("zhang""w""h"11);  
  7.         ms.marshal(st, System.out);  
  8.     } catch (JAXBException e) {  
  9.         // TODO Auto-generated catch block  
  10.         e.printStackTrace();  
  11.     }  
  12. }  
	@Test
public void test01(){
try {
JAXBContext jc = JAXBContext.newInstance(Student.class);
Marshaller ms = jc.createMarshaller();
Student st = new Student("zhang", "w", "h", 11);
ms.marshal(st, System.out);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


 

XmlToJava

  1. //xml转换Java  
  2. @Test  
  3. public void test02() throws JAXBException{  
  4.     String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><student><age>11</age><height>h</height><name>zhang</name><width>w</width></student>";  
  5.     JAXBContext jc = JAXBContext.newInstance(Student.class);  
  6.     Unmarshaller unmar = jc.createUnmarshaller();  
  7.     Student stu = (Student) unmar.unmarshal(new StringReader(xml));  
  8.     System.out.println(stu.getName());  
  9. }  

 

 

 

用的是jdk自带的javax.xml.bind.JAXBContext将对象和xml字符串进行相互转换。

       如果对要生成的 xml 格式有点些许的限制,就会对生成xml的对象就需要进行些许控制,控制对象的一个最可行的办法就是用注解。
 
       比较常用的几个:
       @XmlRootElement:根节点
       @XmlAttribute:该属性作为xml的attribute
       @XmlElement:该属性作为xml的element,且可以增加属性(name="NewElementName"),那么生成的xml串的elment的标签是NewElementName

        示例:    
       
  1. package test;  
  2.   
  3. import java.io.StringWriter;  
  4.   
  5. import javax.xml.bind.JAXBContext;  
  6. import javax.xml.bind.JAXBException;  
  7. import javax.xml.bind.Marshaller;  
  8.   
  9. import test.bean.EleClassA;  
  10. import test.bean.EleClassB;  
  11. import test.bean.RootClass;  
  12.   
  13. public class Test1 {  
  14.   
  15.     public static void main(String[] args) {  
  16.         RootClass rc = new RootClass();  
  17.         EleClassA a = new EleClassA();  
  18.         EleClassB b = new EleClassB();  
  19.           
  20.         a.setAttrC("attrc");  
  21.         a.setEleA("eleA");  
  22.         a.setEleB("eleB");  
  23.           
  24.         b.setAttrPassword("attrPassword");  
  25.         b.setAttrUserName("attrUsrName");  
  26.         b.setEleCode("eleCode");  
  27.           
  28.         rc.setA(a);  
  29.         rc.setB(b);  
  30.         rc.setRoot("root");  
  31.         rc.setRootA("rootA");  
  32.           
  33.           
  34.         JAXBContext context;  
  35.         try {  
  36.             context = JAXBContext.newInstance(RootClass.class);  
  37.             Marshaller mar = context.createMarshaller();  
  38.             mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
  39.             mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");  
  40.               
  41.             StringWriter writer = new StringWriter();  
  42.               
  43.             mar.marshal(rc, writer);  
  44.               
  45.             System.out.println(writer.toString());  
  46.         } catch (JAXBException e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.           
  50.     }  
  51. }  
  52.   
  53.   
  54. package test.bean;  
  55.   
  56. import javax.xml.bind.annotation.XmlElement;  
  57. import javax.xml.bind.annotation.XmlRootElement;  
  58.   
  59. @XmlRootElement(name="rootclass")  
  60. public class RootClass {  
  61.   
  62.     private EleClassA a;  
  63.     private EleClassB b;  
  64.     private String root;  
  65.     private String rootA;  
  66.       
  67.     @XmlElement(name="eleClassA")  
  68.     public EleClassA getA() {  
  69.         return a;  
  70.     }  
  71.     public void setA(EleClassA a) {  
  72.         this.a = a;  
  73.     }  
  74.     @XmlElement(name="EleclassA")  
  75.     public EleClassB getB() {  
  76.         return b;  
  77.     }  
  78.     public void setB(EleClassB b) {  
  79.         this.b = b;  
  80.     }  
  81.     public String getRoot() {  
  82.         return root;  
  83.     }  
  84.     public void setRoot(String root) {  
  85.         this.root = root;  
  86.     }  
  87.     public String getRootA() {  
  88.         return rootA;  
  89.     }  
  90.     public void setRootA(String rootA) {  
  91.         this.rootA = rootA;  
  92.     }  
  93.       
  94. }  
  95.   
  96.   
  97. package test.bean;  
  98.   
  99. import javax.xml.bind.annotation.XmlAttribute;  
  100. import javax.xml.bind.annotation.XmlElement;  
  101.   
  102. public class EleClassA {  
  103.   
  104.     private String eleA;  
  105.     private String eleB;  
  106.       
  107.     private String attrC;  
  108.   
  109.     @XmlElement  
  110.     public String getEleA() {  
  111.         return eleA;  
  112.     }  
  113.   
  114.     public void setEleA(String eleA) {  
  115.         this.eleA = eleA;  
  116.     }  
  117.   
  118.     @XmlElement(name="elebnewname")  
  119.     public String getEleB() {  
  120.         return eleB;  
  121.     }  
  122.   
  123.     public void setEleB(String eleB) {  
  124.         this.eleB = eleB;  
  125.     }  
  126.   
  127.     @XmlAttribute()  
  128.     public String getAttrC() {  
  129.         return attrC;  
  130.     }  
  131.   
  132.     public void setAttrC(String attrC) {  
  133.         this.attrC = attrC;  
  134.     }  
  135.       
  136. }  
  137.   
  138.   
  139. package test.bean;  
  140.   
  141. import javax.xml.bind.annotation.XmlAttribute;  
  142. import javax.xml.bind.annotation.XmlElement;  
  143.   
  144. public class EleClassB {  
  145.   
  146.     private String attrUserName;  
  147.     private String attrPassword;  
  148.       
  149.     private String eleCode;  
  150.       
  151.     @XmlAttribute  
  152.     public String getAttrUserName() {  
  153.         return attrUserName;  
  154.     }  
  155.     public void setAttrUserName(String attrUserName) {  
  156.         this.attrUserName = attrUserName;  
  157.     }  
  158.     @XmlAttribute(name="password")  
  159.     public String getAttrPassword() {  
  160.         return attrPassword;  
  161.     }  
  162.     public void setAttrPassword(String attrPassword) {  
  163.         this.attrPassword = attrPassword;  
  164.     }  
  165.     @XmlElement  
  166.     public String getEleCode() {  
  167.         return eleCode;  
  168.     }  
  169.     public void setEleCode(String eleCode) {  
  170.         this.eleCode = eleCode;  
  171.     }  
  172.       
  173.       
  174. }  
package test;

import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import test.bean.EleClassA;
import test.bean.EleClassB;
import test.bean.RootClass;

public class Test1 {

public static void main(String[] args) {
RootClass rc = new RootClass();
EleClassA a = new EleClassA();
EleClassB b = new EleClassB();

a.setAttrC("attrc");
a.setEleA("eleA");
a.setEleB("eleB");

b.setAttrPassword("attrPassword");
b.setAttrUserName("attrUsrName");
b.setEleCode("eleCode");

rc.setA(a);
rc.setB(b);
rc.setRoot("root");
rc.setRootA("rootA");


JAXBContext context;
try {
context = JAXBContext.newInstance(RootClass.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

StringWriter writer = new StringWriter();

mar.marshal(rc, writer);

System.out.println(writer.toString());
} catch (JAXBException e) {
e.printStackTrace();
}

}
}


package test.bean;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="rootclass")
public class RootClass {

private EleClassA a;
private EleClassB b;
private String root;
private String rootA;

@XmlElement(name="eleClassA")
public EleClassA getA() {
return a;
}
public void setA(EleClassA a) {
this.a = a;
}
@XmlElement(name="EleclassA")
public EleClassB getB() {
return b;
}
public void setB(EleClassB b) {
this.b = b;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public String getRootA() {
return rootA;
}
public void setRootA(String rootA) {
this.rootA = rootA;
}

}


package test.bean;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

public class EleClassA {

private String eleA;
private String eleB;

private String attrC;

@XmlElement
public String getEleA() {
return eleA;
}

public void setEleA(String eleA) {
this.eleA = eleA;
}

@XmlElement(name="elebnewname")
public String getEleB() {
return eleB;
}

public void setEleB(String eleB) {
this.eleB = eleB;
}

@XmlAttribute()
public String getAttrC() {
return attrC;
}

public void setAttrC(String attrC) {
this.attrC = attrC;
}

}


package test.bean;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

public class EleClassB {

private String attrUserName;
private String attrPassword;

private String eleCode;

@XmlAttribute
public String getAttrUserName() {
return attrUserName;
}
public void setAttrUserName(String attrUserName) {
this.attrUserName = attrUserName;
}
@XmlAttribute(name="password")
public String getAttrPassword() {
return attrPassword;
}
public void setAttrPassword(String attrPassword) {
this.attrPassword = attrPassword;
}
@XmlElement
public String getEleCode() {
return eleCode;
}
public void setEleCode(String eleCode) {
this.eleCode = eleCode;
}


}

运行Test1类中main方法,执行结果:
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2. <rootclass>  
  3.     <eleClassA attrC="attrc">  
  4.         <eleA>eleA</eleA>  
  5.         <elebnewname>eleB</elebnewname>  
  6.     </eleClassA>  
  7.     <EleclassA attrUserName="attrUsrName" password="attrPassword">  
  8.         <eleCode>eleCode</eleCode>  
  9.     </EleclassA>  
  10.     <root>root</root>  
  11.     <rootA>rootA</rootA>  
  12. </rootclass>  

 

 

JAXB(Java API for XML Binding),提供了一个快速便捷的方式将Java对象与XML进行转换。在JAX-WS(Java的WebService规范之一)中,JDK1.6 自带的版本JAX-WS2.1,其底层支持就是JAXB

    JAXB 可以实现Java对象与XML的相互转换,在JAXB中,将一个Java对象转换为XML的过程称之为Marshal,将XML转换为Java对象的过程称之为UnMarshal。我们可以通过在 Java 类中标注注解的方式将一个Java对象绑定到一段XML,也就是说,在Java类中标注一些注解,这些注解定义了如何将这个类转换为XML,怎么转换,以及一段XML如何被解析成这个类所定义的对象;也可以使用JAXB的XJC工具,通过定义schema的方式实现Java对象与XML的绑定(这个下次研究)。

    下面来了解一下如何通过标注注解来完成 Marshal 和 UnMarshal 的过程。我用的是 JAXB2_20101209.jar ,可以到http://jaxb.java.net/下载最新版本。

 

首先看个小例子:



定义一个java类

Java代码
package com.why.jaxb;   
 
import javax.xml.bind.annotation.XmlRootElement;   
 
@XmlRootElement  
public class People {   
    public String id = "001";   
    public String name = "灰太狼";   
    public int age = 26;   
}  

//我们在实际中一般在get方法上添加相关注解
Java To XML(Marshal)

Java代码
package com.why.jaxb;   
 
import javax.xml.bind.JAXBContext;   
import javax.xml.bind.JAXBException;   
import javax.xml.bind.Marshaller;   
 
public class Java2XML {   
 
    /**  
     * @param args  
     * @throws JAXBException   
     */  
    public static void main(String[] args) throws JAXBException {   
        JAXBContext context = JAXBContext.newInstance(People.class);   
           
        Marshaller marshaller = context.createMarshaller();   
        marshaller.setProperty(Marshaller.JAXB_ENCODING,"gb2312");//编码格式

        //我在实际开发中重新封装了JAXB基本类,这里就使用到了该属性。不过默认的编码格式UTF-8

        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//是否格式化生成的xml串   
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);//是否省略xml头信息(<?xml version="1.0" encoding="gb2312" standalone="yes"?>)   
           
        People people = new People();   
        marshaller.marshal(people, System.out);   
    }   
 
}  

XML To Java(UnMarshal)

Java代码
package com.why.jaxb;   
 
import java.io.File;   
import javax.xml.bind.JAXBContext;   
import javax.xml.bind.JAXBException;   
import javax.xml.bind.Unmarshaller;   
import org.xml.sax.SAXException;   
 
public class XML2Java {   
    /**  
     * @param args  
     * @throws JAXBException   
     * @throws JAXBException   
     * @throws SAXException   
     */  
    public static void main(String[] args) throws JAXBException {   
        JAXBContext context = JAXBContext.newInstance(People.class);   
        Unmarshaller unmarshaller = context.createUnmarshaller();   
        File file = new File("src/people.xml");   
        People people = (People)unmarshaller.unmarshal(file);   
        System.out.println(people.id);   
        System.out.println(people.name);   
        System.out.println(people.age);   
    }   
}

 

       其实Marshal 和 UnMarshal的过程并不复杂,只需要从JAXBContext中获得Marshaller或Unmarshaller对象,就可以让JAXB帮我们来进行转换了。我们需要操作的主要内容是定义一个规则,告诉JAXB如何将一个类、按照什么样的格式转换为XML,下面是JAXB中主要的一些注解。



@XmlRootElement   将一个Java类映射为一段XML的根节点

参数:name            定义这个根节点的名称

          namespace   定义这个根节点命名空间



@XmlAccessorType  定义映射这个类中的何种类型需要映射到XML。可接收四个参数,分别是:

      XmlAccessType.FIELD:映射这个类中的所有字段到XML

      XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML

      XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)

      XmlAccessType.NONE:不映射



@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)



@XmlTransient  定义某一字段或属性不需要被映射为XML。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一get/set方法的字段上标注此注解,那么该属性则不会被映射。



@XmlType 定义映射的一些相关规则

参数:propOrder        指定映射XML时的节点顺序

         factoryClass     指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身

         factoryMethod  指定工厂类的工厂方法

         name               定义XML Schema中type的名称

         namespace      指定Schema中的命名空间



@XmlElementWrapper  为数组元素或集合元素定义一个父节点。如,类中有一元素为List items,若不加此注解,该元素将被映射为

    <items>...</items>

    <items>...</items>

这种形式,此注解可将这个元素进行包装,如:

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

将会生成这样的XML样式:

    <items>

        <item>...</item>

        <item>...</item>

    </items>



@XmlJavaTypeAdapter  自定义某一字段或属性映射到XML的适配器。如,类中包含一个接口,我们可以定义一个适配器(继承自 javax.xml.bind.annotation.adapters.XmlAdapter类),指定这个接口如何映射到XML。



@XmlSchema 配置整个包的namespace,这个注解需放在package-info.java文件中。

jaxb编码:

           JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            InputStreamReader reader=new InputStreamReader(inputStream,"GBK");   //在此修改编码
            return unmarshaller.unmarshal(reader);

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在JAXB中(用于JAVA对象和xml之间的转换),经常出现各类的 @XmlElement这样的标记,
下面就来以一个例子小结下,加深学习:

Java代码
  1.   
  2. import java.util.*;   
  3. import javax.xml.bind.annotation.*;   
  4.     
  5. @XmlRootElement  
  6. @XmlAccessorType(XmlAccessType.FIELD)   
  7. public class Customer {   
  8.     
  9.     private List<String> emailAddresses;   
  10.         
  11.     public Customer() {   
  12.         emailAddresses = new ArrayList<String>();   
  13.     }   
  14.     
  15.     public List<String> getEmailAddresses() {   
  16.         return emailAddresses;   
  17.     }   
  18.     
  19.     public void setEmailAddresses(List<String> emailAddresses) {   
  20.         this.emailAddresses = emailAddresses;   
  21.     }   
  22.     
  23. }  



这个是一个典型的POJO了,其中引用了对象emailAddress,是一个List,那么下面演示各类用法:
  先看默认的调用代码如下:

Java代码
  1. import javax.xml.bind.JAXBContext;   
  2. import javax.xml.bind.Marshaller;   
  3.     
  4. public class Demo {   
  5.     
  6.     public static void main(String[] args) throws Exception {   
  7.         JAXBContext jc = JAXBContext.newInstance(Customer.class);   
  8.     
  9.         Customer customer = new Customer();   
  10.         customer.getEmailAddresses().add("janed@example.com");   
  11.         customer.getEmailAddresses().add("jdoe@example.org");   
  12.     
  13.         Marshaller marshaller = jc.createMarshaller();   
  14.         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);   
  15.         marshaller.marshal(customer, System.out);   
  16.     }   
  17. }  



  默认的把这个对象输出为一般的XML:
<customer>
    <emailAddresses>janed@example.com</emailAddresses>
    <emailAddresses>jdoe@example.org</emailAddresses>
</customer>

下面逐一看每个注解的用法
1) @XmlElement
  
@XmlElement(name="email-address")
    private List<String> emailAddresses;
加上这个注解的话,则按自定义的xml标签名去输出某个属性,如下:
<customer>
    <email-address>janed@example.com</email-address>
    <email-address>jdoe@example.org</email-address>
</customer>

2) @XmlElementWrapper
  这个注解等于在最外面再包一层了,
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    @XmlElementWrapper(name="email-addresses")
    @XmlElement(name="email-address")
    private List<String> emailAddresses;

}
  输出:
<customer>
    <email-addresses>
        <email-address>janed@example.com</email-address>
        <email-address>jdoe@example.org</email-address>
    </email-addresses>
</customer>


3) @XmlList
  这个等于是在同一行中,把list中的输出,以空格形式分隔开来,

Java代码
  1. @XmlRootElement  
  2. @XmlAccessorType(XmlAccessType.FIELD)   
  3. public class Customer {   
  4.     
  5.     @XmlList  
  6.     private List<String> emailAddresses;   
  7.     
  8. }  



  输出:
  <customer>
    <emailAddresses>janed@example.com jdoe@example.org</emailAddresses>
</customer>

4)
@XmlList和 @XmlAttribute混合使用
      @XmlList
    @XmlAttribute
    private List<String> emailAddresses;

输出:
   <customer
    emailAddresses="janed@example.com jdoe@example.org"/>

看到没?就是同一行中逗号输出,并作为customer的一个属性


5)
  @XmlList 和 @XmlValue混用
   
    @XmlList
    @XmlValue
    private List<String> emailAddresses;
 

就是把emailAddress的list的值,作为<customer>的value  输出,结果如下:
<customer>janed@example.com jdoe@example.org</customer>

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

一.Jaxb处理java对象和xml之间转换常用的annotation有:

  1. @XmlType
  2. @XmlElement
  3. @XmlRootElement
  4. @XmlAttribute
  5. @XmlAccessorType
  6. @XmlAccessorOrder
  7. @XmlTransient
  8. @XmlJavaTypeAdapter

 二.常用annotation使用说明

 

  1. @XmlType

  @XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:

@XmlType(name = "basicStruct", propOrder = {
"intValue",
"stringArray",
"stringValue"
)
在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。

  2.@XmlElement

  @XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:

  @XmlElement(name="Address")   
  private String yourAddress;

  3.@XmlRootElement

  @XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:

  @XmlType
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlRootElement
  public class Address {}

  4.@XmlAttribute

  @XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
  @XmlAttribute(name="Country")
  private String state;

  5.@XmlAccessorType

  @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分   别为:

  XmlAccessType.FIELD:java对象中的所有成员变量

  XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量

  XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量

  XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素

  注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在   private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。同理,如果@XmlAccessorType的访问权限   为XmlAccessType.NONE,如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。

  6.@XmlAccessorOrder

  @XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:

  AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序

  XmlAccessOrder.UNDEFINED:不排序

  7.@XmlTransient

  @XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。

  8.@XmlJavaTypeAdapter

  @XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。

  @XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类

  XmlAdapter如下:

public abstract class XmlAdapter<ValueType,BoundType> {
// Do-nothing constructor for the derived classes.
protected XmlAdapter() {}
// Convert a value type to a bound type.
public abstract BoundType unmarshal(ValueType v);
// Convert a bound type to a value type.
public abstract ValueType marshal(BoundType v);
}

 三.示例

  1.Shop.java

?
package jaxb.shop;
 
import java.util.Set;
 
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlAccessorOrder;
 
@XmlAccessorOrder (XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType (XmlAccessType.FIELD)
@XmlType (name = "shop" , propOrder = { "name" , "number" , "describer" , "address" , "orders" })
?
@XmlRootElement (name = "CHMart" )
public class Shop {
 
     @XmlAttribute
     private String name;
 
     // @XmlElement
     private String number;
 
     @XmlElement
     private String describer;
 
     @XmlElementWrapper (name = "orders" )
     @XmlElement (name = "order" )
     private Set<Order> orders;
 
     @XmlElement
     private Address address;
 
     public Shop() {
     }
 
     public Shop(String name, String number, String describer, Address address) {
         this .name = name;
         this .number = number;
         this .describer = describer;
         this .address = address;
     }
 
     getter/setter略
?
//同时使用了@XmlType(propOrder={})和@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL),但是生成的xml只按照propOrder定义的顺序生成元素

  2.Order.java

?
package jaxb.shop;
 
import java.math.BigDecimal;
import java.util.Date;
 
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
@XmlType (name= "order" ,propOrder={ "shopName" , "orderNumber" , "price" , "amount" , "purDate" , "customer" })
@XmlAccessorType (XmlAccessType.FIELD)
@XmlRootElement
public class Order {
 
//  @XmlElement  
     private String shopName;
 
     @XmlAttribute
     private String orderNumber;
 
//  @XmlElement
     @XmlJavaTypeAdapter (value=DateAdapter. class )
     private Date purDate;
 
//  @XmlElement
     private BigDecimal price;
 
//  @XmlElement
     private int amount;
 
//  @XmlElement
     private Customer customer;
 
     public Order() {
     }
 
     public Order(String shopName, String orderNumber, Date purDate,
             BigDecimal price, int amount) {
         this .shopName = shopName;
         this .orderNumber = orderNumber;
         this .purDate = purDate;
         this .price = price;
         this .amount = amount;
     }
?
getter/setter略
?
//@XmlAccessorType(XmlAccessType.FIELD),所以此处注释掉了@XmlElement,xml中依然会生成这些元素

  3.Customer.java

?
package jaxb.shop;
 
import java.util.Set;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
 
@XmlType
@XmlAccessorType (XmlAccessType.FIELD)
@XmlRootElement
public class Customer {
 
     @XmlAttribute
     private String name;
 
     private String gender;
 
     private String phoneNo;
 
     private Address address;
 
     private Set<Order> orders;
 
     public Customer() {
     }
 
     public Customer(String name, String gender, String phoneNo, Address address) {
         this .name = name;
         this .gender = gender;
         this .phoneNo = phoneNo;
         this .address = address;
     }
?
getter/setter略

  4.Address.java

?
package jaxb.shop;
 
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessorOrder;
 
@XmlType (propOrder={ "state" , "province" , "city" , "street" , "zip" })
@XmlAccessorOrder (XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType (XmlAccessType.NONE)
@XmlRootElement
public class Address {
 
     @XmlAttribute  
     private String state;
     
     @XmlElement
     private String province;
     
     @XmlElement
     private String city;
 
     @XmlElement
     private String street;
     
     @XmlElement
     private String zip;
 
     public Address() {
         super ();
     }
 
     public Address(String state, String province, String city, String street,
             String zip) {
         super ();
         this .state = state;
         this .province = province;
         this .city = city;
         this .street = street;
         this .zip = zip;
     }
?
getter/setter略
?
//注意:虽然@XmlAccessorType为XmlAccessType.NONE,但是在java类的私有属性上加了@XmlAttribute和@XmlElement注解后,这些私有成员会映射生成xml的元素

  5.DateAdapter.java

?
package jaxb.shop;
 
import java.util.Date;
import java.text.SimpleDateFormat;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
 
public class DateAdapter extends XmlAdapter<String, Date> {
 
     private String pattern = "yyyy-MM-dd HH:mm:ss" ;
     SimpleDateFormat fmt = new SimpleDateFormat(pattern);
     
     @Override
     public Date unmarshal(String dateStr) throws Exception {
         
         return fmt.parse(dateStr);
     }
 
     @Override
     public String marshal(Date date) throws Exception {
         
         return fmt.format(date);
     }
 
}
?
//用于格式化日期在xml中的显示格式,并且由xml unmarshal为java对象时,将字符串解析为Date对象

  6.ShopTest.java

?
package jaxb.shop;
 
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
 
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
 
public class ShopTest {
 
     public static void main(String[] args) throws JAXBException, IOException{
         Set<Order> orders = new HashSet<Order>();
         
         Address address1 = new Address( "China" , "ShangHai" , "ShangHai" , "Huang" , "200000" );
         Customer customer1 = new Customer( "Jim" , "male" , "13699990000" , address1);
         Order order1 = new Order( "Mart" , "LH59900" , new Date(), new BigDecimal( 60 ), 1 );
         order1.setCustomer(customer1);
         
         Address address2 = new Address( "China" , "JiangSu" , "NanJing" , "ZhongYangLu" , "210000" );
         Customer customer2 = new Customer( "David" , "male" , "13699991000" , address2);
         Order order2 = new Order( "Mart" , "LH59800" , new Date(), new BigDecimal( 80 ), 1 );
         order2.setCustomer(customer2);
         
         orders.add(order1);
         orders.add(order2);
         
         Address address3 = new Address( "China" , "ZheJiang" , "HangZhou" , "XiHuRoad" , "310000" );
         Shop shop = new Shop( "CHMart" , "100000" , "EveryThing" ,address3);
         shop.setOrder(orders);
         
         
         FileWriter writer = null ;
         JAXBContext context = JAXBContext.newInstance(Shop. class );
         try {
             Marshaller marshal = context.createMarshaller();
             marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true );
             marshal.marshal(shop, System.out);
             
             writer = new FileWriter( "shop.xml" );
             marshal.marshal(shop, writer);
         } catch (Exception e) {
             e.printStackTrace();
         }
         
         Unmarshaller unmarshal = context.createUnmarshaller();
         FileReader reader = new FileReader( "shop.xml" ) ;
         Shop shop1 = (Shop)unmarshal.unmarshal(reader);
         
         Set<Order> orders1 = shop1.getOrder();
         for (Order order : orders1){
             System.out.println( "***************************" );
             System.out.println(order.getOrderNumber());
             System.out.println(order.getCustomer().getName());
             System.out.println( "***************************" );
         }
     }
}

  7.生成的xml文件

?
<?xml version= "1.0" encoding= "UTF-8" standalone= "yes" ?>
<CHMart name= "CHMart" >
     <number> 100000 </number>
     <describer>EveryThing</describer>
     <address state= "China" >
         <province>ZheJiang</province>
         <city>HangZhou</city>
         <street>XiHuRoad</street>
         <zip> 310000 </zip>
     </address>
     <orders>
         <order orderNumber= "LH59800" >
             <shopName>Mart</shopName>
             <price> 80 </price>
             <amount> 1 </amount>
             <purDate> 2012 - 03 - 25 12 : 57 : 23 </purDate>
             <customer name= "David" >
                 <gender>male</gender>
                 <phoneNo> 13699991000 </phoneNo>
                 <address state= "China" >
                     <province>JiangSu</province>
                     <city>NanJing</city>
                     <street>ZhongYangLu</street>
                     <zip> 210000 </zip>
                 </address>
             </customer>
         </order>
         <order orderNumber= "LH59900" >
             <shopName>Mart</shopName>
             <price> 60 </price>
             <amount> 1 </amount>
             <purDate> 2012 - 03 - 25 12 : 57 : 23 </purDate>
             <customer name= "Jim" >
                 <gender>male</gender>
                 <phoneNo> 13699990000 </phoneNo>
                 <address state= "China" >
                     <province>ShangHai</province>
                     <city>ShangHai</city>
                     <street>Huang</street>
                     <zip> 200000 </zip>
                 </address>
             </customer>
         </order>
     </orders>
</CHMart>