JAXB 可以实现Java对象与XML的相互转换

来源:互联网 发布:织梦58公司 编辑:程序博客网 时间:2024/04/30 21:03


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

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


项目整体结构如下:


1.建立三个实体


People.java

package com.hys.demo.entity;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name = "people",namespace="abc")//设置根节点@XmlAccessorType(XmlAccessType.FIELD)public class People {      public String id;     public String name;        public int age;  public People() {   } public People(String id, String name, int age) {  this.id = id;  this.name = name;  this.age = age; } public String getId() {  return id; } public void setId(String id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public int getAge() {  return age; } public void setAge(int age) {  this.age = age; } }

TestObj.java

package com.hys.demo.entity;import java.util.Date;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;@XmlAccessorType(XmlAccessType.FIELD)public class TestObj { private long id; private String name;  private Date birthday;  public TestObj() {  } public TestObj(long id, String name, Date birthday) {  this.id = id;  this.name = name;  this.birthday = birthday; } public long getId() {  return id; }  public void setId(long id) {  this.id = id; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } public Date getBirthday() {  return birthday; } public void setBirthday(Date birthday) {  this.birthday = birthday; }}

ObjList.java

package com.hys.demo.entity;import java.util.ArrayList;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 com.hys.demo.entity.TestObj;@XmlRootElement(name = "peoples")@XmlAccessorType(XmlAccessType.FIELD)public class ObjList {    @XmlAttribute(name = "size")    private int size;        @XmlElement(name = "people")    private ArrayList<TestObj> objList;     public int getSize() {        return size;    }    public void setSize(int size) {        this.size = size;    } public ArrayList<TestObj> getObjList() {  return objList; } public void setObjList(ArrayList<TestObj> objList) {  this.objList = objList; }}

2Xml文件

test.xml

<?xml version="1.0" encoding="UTF-8"?><peoples size="7095">    <people>        <id>16817</id>        <name>张三01</name>        <birthday>2011-12-28</birthday>    </people>    <people>        <id>16817</id>        <name>张三02</name>        <birthday>2011-12-28</birthday>    </people>    <people>        <id>16817</id>        <name>张三03</name>        <birthday>2011-12-28</birthday>    </people></peoples>

people.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:people xmlns:ns2="abc">    <id>001</id>    <name>灰太狼</name>    <age>22</age></ns2:people>

Java To XMLMarshal 


JaxbWriteXml.java

package com.hys.demo.marshal;import java.util.ArrayList;import java.util.Date;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import org.junit.Test;import com.hys.demo.entity.ObjList;import com.hys.demo.entity.People;import com.hys.demo.entity.TestObj;public class JaxbWriteXml {public static <T> Marshaller getMarshaller(Class<T> c) throws JAXBException{JAXBContext context = JAXBContext.newInstance(c);Marshaller marshaller = context.createMarshaller(); //编码格式 marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");//是否格式化生成的xml串    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//是否省略xml头信息(<?xml version="1.0" encoding="gb2312" standalone="yes"?>)marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);return marshaller;}@Testpublic void test_xml() throws JAXBException{Marshaller marshaller = getMarshaller(People.class);        People people = new People("001","灰太狼",22);          marshaller.marshal(people, System.out);   }@Testpublic void test_xml2() throws JAXBException{Marshaller marshaller = getMarshaller(ObjList.class);        ArrayList<TestObj> list = new ArrayList<TestObj>();         TestObj testObj1 = new TestObj(111, "灰太狼", new Date());        TestObj testObj2 = new TestObj(222, "灰太狼", new Date());        list.add(testObj1);        list.add(testObj2);                ObjList objlist = new ObjList();        objlist.setObjList(list);        marshaller.marshal(objlist, System.out);}}

测试结果1

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:people xmlns:ns2="abc">    <id>001</id>    <name>灰太狼</name>    <age>22</age></ns2:people>

测试结果2

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><peoples size="0">    <people>        <id>111</id>        <name>灰太狼</name>        <birthday>2017-01-11T17:10:01.181+08:00</birthday>    </people>    <people>        <id>222</id>        <name>灰太狼</name>        <birthday>2017-01-11T17:10:01.182+08:00</birthday>    </people></peoples>

XML To JavaUnMarshal

JaxbReadXml.java

package com.hys.demo.unMarshal;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.text.MessageFormat;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Unmarshaller;import org.junit.Test;import com.hys.demo.entity.ObjList;import com.hys.demo.entity.People;import com.hys.demo.entity.TestObj;public class JaxbReadXml {    @SuppressWarnings("unchecked")    public static <T> T readString(Class<T> clazz, String context) throws JAXBException, IOException {        try {        InputStream inputStream = ClassLoader.getSystemResource(context).openStream();            JAXBContext jc = JAXBContext.newInstance(clazz);            Unmarshaller u = jc.createUnmarshaller();            return (T) u.unmarshal(inputStream);        } catch (JAXBException e) {            throw e;        }    }    @SuppressWarnings("unchecked")    public static <T> T readConfig(Class<T> clazz, String config, Object... arguments) throws IOException,            JAXBException {        InputStream is = null;        try {            if (arguments.length > 0) {                config = MessageFormat.format(config, arguments);            }            // logger.trace("read configFileName=" + config);            JAXBContext jc = JAXBContext.newInstance(clazz);            Unmarshaller u = jc.createUnmarshaller();            is = new FileInputStream(config);            return (T) u.unmarshal(is);        } catch (IOException e) {            // logger.trace(config, e);            throw e;        } catch (JAXBException e) {            // logger.trace(config, e);            throw e;        } finally {            if (is != null) {                is.close();            }        }    }    @SuppressWarnings("unchecked")    public static <T> T readConfigFromStream(Class<T> clazz, InputStream dataStream) throws JAXBException {        try {            JAXBContext jc = JAXBContext.newInstance(clazz);            Unmarshaller u = jc.createUnmarshaller();            return (T) u.unmarshal(dataStream);        } catch (JAXBException e) {            // logger.trace(e);            throw e;        }    }    @Test    public void test_xml() throws JAXBException, IOException{        ObjList arrayObj = JaxbReadXml.readString(ObjList.class, "test.xml");        System.out.println(arrayObj.getSize());                for (TestObj testObj : arrayObj.getObjList()) {System.out.println("姓名:"+testObj.getName()+"  出生日期:"+testObj.getBirthday());}    }        @Test    public void test_xml1() throws JAXBException, IOException{        People People = JaxbReadXml.readString(People.class, "people.xml");    System.out.println("姓名:"+People.getName()+"  年龄:"+People.getAge());    }}

测试结果1

7095姓名:张三01  出生日期:Wed Dec 28 00:00:00 CST 2011姓名:张三02  出生日期:Wed Dec 28 00:00:00 CST 2011姓名:张三03  出生日期:Wed Dec 28 00:00:00 CST 2011

测试结果2

姓名:灰太狼  年龄:22

其实Marshal UnMarshal的过程并不复杂,只需要从JAXBContext中获得MarshallerUnmarshaller对象,就可以让JAXB帮我们来进行转换了。

我们需要操作的主要内容是定义一个规则,告诉JAXB如何将一个类、按照什么样的格式转换为XML,下面是JAXB中主要的一些注解。

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

参数:name定义这个根节点的名称;namespace  定义这个根节点命名空间

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

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

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

     XmlAccessType.PUBLIC_MEMBER:将这个类中的所有publicfieldproperty同时映射到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 Schematype的名称 

        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=newInputStreamReader(inputStream,"GBK");  //在此修改编码

           return unmarshaller.unmarshal(reader);


其他:

对于要序列化(marshal)为XMLJava类,绝不能把成员变量声明为public,否则运行将抛出异常com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException

对于JAXB相关的重要Annotation的声明,如@Xml.....,可以放在成员变量的setter()getter()方法上,两者中任选其一即可,但决不能放在成员变量上,否则运行将抛出异常com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException

缺省的数据类型绑定

下面的表格列出了JAXBXML数据类型和Java数据类型的映射。

XML Schema类型

Java数据类型

xsd:string

java.lang.String

xsd:positiveInteger

java.math.BigInteger

xsd:int

int

xsd:long

long

xsd:short

short

xsd:decimal

java.math.BigDecimal

xsd:float

float

xsd:double

double

xsd:boolean

boolean

xsd:byte

byte

xsd:QName

javax.xml.namespace.QName

xsd:dateTime

javax.xml.datatype.XMLGregorianCalendar

xsd:base64Binary

byte[]

xsd:hexBinary

byte[]

xsd:unsignedInt

long

xsd:unsignedShort

int

xsd:unsignedByte

short

xsd:time

javax.xml.datatype.XMLGregorianCalendar

xsd:date

javax.xml.datatype.XMLGregorianCalendar

xsd:g

javax.xml.datatype.XMLGregorianCalendar

xsd:anySimpleType

java.lang.Object

xsd:anySimpleType

java.lang.String

xsd:duration

javax.xml.datatype.Duration

xsd:NOTATION

javax.xml.namespace.QName


0 0
原创粉丝点击