通过JAXB注解,根据java类生成xml内容

来源:互联网 发布:网络代维管理系统下载 编辑:程序博客网 时间:2024/05/22 15:49
1. 什么是JAXB
    Java  Architecture for XML Binding (JAXB)是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。

    这意味着你不需要处理甚至不需要知道XML编程技巧就能在Java应用程序中利用平台核心XML数据的灵活性。而且,可以充分利用XML的优势而不用依赖于复杂的XML处理模型如SAXDOMJAXB隐藏了细节并且取消了SAXDOM中没用的关系——生成的JAXB类仅描述原始模型中定义的关系。其结果是结合了高度可移植Java代码和高度可移植的XML数据。其中这些代码可用来创建灵活、轻便的应用程序和Web服务。

2. JAXB的体系结构
JAXB学习 - mengshj - 可可的梦幻世界

JAXB的体系结构和应用过程如图所示,一般来说包含以下几个步骤:

1)        根据你的应用程序所要操作的XML数据格式,撰写相应的XML Schema,有关XML Schema的知识,请参阅“参考资料”

2)        使用JAXB所带的编译工具(Binding Compiler),将这个XML Schema文件作为输入,产生一系列相关的Java ClassInterface

3)        在使用JAXB编译工具的时候,可以有选择性的提供一个配置文件(图的虚线部分),来控制JAXB编译工具的一些高级属性。

4)        这些Java ClassInterface是你的应用程序操纵XML数据的主要接口和方法。

5)        通过JAXBXML文档进行的操作主要包括:将符合XML Schema规定的XML文档解析生成一组相应的Java对象;对这些对象进行操作(修改、增加和删除对象的属性等等);然后将这些对象的内容保存到这个XML文档中。

3、JAXB相关的重要Annotation@XmlRootElement,将Java类或枚举类型映射到XML元素。

@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE。

@XmlElement,将Java类的一个属性映射到与属性同名的一个XML元素。

@XmlType,将Java类或枚举类型映射到XML模式类型

@XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序。
@XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。
@XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)。
@XmlAttribute,将Java类的一个属性映射到与属性同名的一个XML属性。

XmlAccessorType 
默认规则:
默认情况下,如果包中不存在 @XmlAccessorType,那么假定使用以下包级别注释。
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
默认情况下,如果类中不存在 @XmlAccessorType,并且没有任何超类是使用 @XmlAccessorType 注释的,则假定在类中使用以下默认注释:
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
可能值:
FIELD:    JAXB 绑定类中的每个非静态、非瞬态字段将会自动绑定到 XML,除非由 XmlTransient 注释。
NONE:     所有字段或属性都不能绑定到 XML,除非使用一些 JAXB 注释专门对它们进行注释。
PROPERTY: JAXB 绑定类中的每个获取方法/设置方法对将会自动绑定到 XML,除非由 XmlTransient 注释。
PUBLIC_MEMBER:每个公共获取方法/设置方法对和每个公共字段将会自动绑定到 XML,除非由 XmlTransient 注释。

应用参考:http://blog.sina.com.cn/s/blog_4051f5dc0100ju0a.html


    package jaxb;      import javax.xml.bind.annotation.XmlAccessorType;      import javax.xml.bind.annotation.XmlRootElement;      import javax.xml.bind.annotation.XmlAccessType;            @XmlRootElement // 必须要标明这个元素      @XmlAccessorType(XmlAccessType.FIELD)      public class Boy {             String name = "CY";      }            package jaxb;            import java.io.StringReader;      import javax.xml.bind.JAXBContext;      import javax.xml.bind.JAXBException;      import javax.xml.bind.Marshaller;      import javax.xml.bind.Unmarshaller;            public class JAXBTest {                public static void main(String[] args) throws JAXBException {              JAXBContext context = JAXBContext.newInstance(Boy.class);                           Marshaller marshaller = context.createMarshaller();              Unmarshaller unmarshaller = context.createUnmarshaller();                           Boy boy = new Boy();              marshaller.marshal(boy, System.out);              System.out.println();                           String xml = "<boy><name>David</name></boy>";              Boy boy2 = (Boy) unmarshaller.unmarshal(new StringReader(xml));              System.out.println(boy2.name);          }      }  
执行结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><boy><name>CY</name></boy>
David
先 是marshall成 xml文件,再是把 xml 文件 unmarshal 成 java object。

改动一:
修改@XmlAccessorType(XmlAccessType.FIELD)  --> @XmlAccessorType(XmlAccessType.PROPERTY)
意思是只有 属性 才能被转换成 xml 中的标签

所以再运行的结果是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><boy/>
CY
就是说 java object 转换成 xml 的时候,name 不是属性(因为没有 get set方法),所以name不转换成标签。

改动二:
在 改动一 的基础上,给name属性添加 get set 方法。 再运行,结果为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><boy><name>CY</name></boy>
David
由 此 可见 @XmlAccessorType 这个annotation 的作用。

改动三:
在改动二 的基础上,给Boy 再添加一个field, int age=10, 即:
    package jaxb;            import javax.xml.bind.annotation.XmlAccessorType;      import javax.xml.bind.annotation.XmlRootElement;      import javax.xml.bind.annotation.XmlAccessType;            @XmlRootElement      @XmlAccessorType(XmlAccessType.PROPERTY)      public class Boy {             String name = "CY";          int age = 10;          public String getName() {              return name;          }          public void setName(String name) {              this.name = name;          }      }  

显然,这个age 是不会被 转化 到xml 文件中的。解决办法是:
    import javax.xml.bind.annotation.XmlAccessorType;      import javax.xml.bind.annotation.XmlElement;      import javax.xml.bind.annotation.XmlRootElement;      import javax.xml.bind.annotation.XmlAccessType;            @XmlRootElement // bixude      @XmlAccessorType(XmlAccessType.PROPERTY)      public class Boy {                   String name = "CY";          @XmlElement          int age = 10;          public String getName() {              return name;          }                public void setName(String name) {              this.name = name;          }            }  

加上 @XmlElement annotation. 运行结果为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><boy><age>10</age> <name>CY</name></boy>
David

对于根元素,可以设置属性:
@XmlRootElement(name="b" nameSpace="http://test")
这样,在生成的xml文件中,<boy> 标签 就会变为 <b> 标签。并且加上一个命名空间。


下面解释 @XmlJavaTypeAdaptor 的作用:
    @XmlRootElement      @XmlAccessorType(XmlAccessType.PROPERTY)      public class Boy {                   private String name = "CY";                private Address address; // 是一个接口                   public String getName() {              return name;          }                public void setName(String name) {              this.name = name;          }            }  

在 java object 转换成 xml 的时候,接口Address 无法被转换。
所以 这里要加上 @XmlJavaTypeAdapter(AddressAdapter.class)
所以 要多写一个AddressAdaptor 类。
这个类会返回Address接口的一个具体实现类的对象。

这 就是 @XmlJavaTypeAdapter 的作用。

2 0