本篇博客为学习笔记。通过学习网上博客总结而作,文字描述部分是总结,代码部分经过学习修改,运行通过。
1. 什么是JAXB
JAXB,是JavaEE的规范,全称Java Architecture for XML Binding。
它是一种可以根据XML Schema产生Java类的技术,JAXB也提供将XML实例文档反向生成java对象树的方法,并将java对象树的内容重新写入XML实例文档。
1.1 java对象与xml互转场景
2. 引入JAXB包
在项目管理文件pom.xml里面,引入jaxb的jar包
<!-- http://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<!-- http://mvnrepository.com/artifact/javax.xml/jaxb-api -->
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- http://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
3. 使用JAXB包
引入了JAXB的包以后,便可以在自己的类上面,使用JAXB提供的类,接口,注解等。
3.1 将java对象转换为XML
package com.liwl.dev;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class LiwanLiangJAXB {
String name;
int age;
int id;
public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
@XmlElement
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
@XmlElement
public void setId(int id) {
this.id = id;
}
@Override
public String toString(){
return "LiwanLiangJAXB [name=" + name + ",age=" + age + ",id=" + id + "]";
}
};
测试程序代码:
package com.liwl.dev;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class MyTest {
public static void main(String[] args) {
LiwlJAXBMarshall liwljaxb = new LiwlJAXBMarshall();
liwljaxb.setName("liwanliang");
liwljaxb.setAge(30);
liwljaxb.setId(100);
try {
File file = new File("/tmp/liwl.xml");//这里产生一个file.xml文件
JAXBContext jaxbContext = JAXBContext.newInstance(LiwlJAXBMarshall.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
jaxbMarshaller.marshal(liwljaxb, file);
jaxbMarshaller.marshal(liwljaxb, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
产生的file.xml内容如下
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<liwlJAXBMarshall>
<age>30</age>
<id>100</id>
<name>liwanliang</name>
</liwlJAXBMarshall>
3.2 将XML转为java对象
将上面代码产生的/tmp/file.xml
,拷贝为/tmp/liwl.xml
,然后通过代码读出。如下:
import javax.xml.bind.Unmarshaller;
...
public class MyTest {
public static void main(String[] args) {
LiwlJAXBMarshall liwljaxb = new LiwlJAXBMarshall();
liwljaxb.setName("liwanliang");
liwljaxb.setAge(30);
liwljaxb.setId(100);
try {
File file = new File("/tmp/liwl.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(LiwlJAXBMarshall.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
LiwlJAXBMarshall liwl = (LiwlJAXBMarshall) jaxbUnmarshaller.unmarshal(file);
System.out.println(liwl);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
4. JAXB相关注解解释
本部分内容摘抄于《Jaxb完全手册》,总结归纳。
JAXBContent类,是应用的入口,用于管理XML/Java绑定信息
Marshaller接口,将java对象序列化为XML数据
Unmarshaller接口,将XML数据反序列化为java对象
@XmlType
用在class的注解。常与@XmlRootElement,@XmlAccessorType一起用。它有三个属性
- name
- propOrder
- namespace
常用前2个属性。
如果同时使用了@XmlType(propOrder={})和@XmlAccessOrder(XmlAccessOrder.ALPHABETICAL)时候,生成的xml只按照propOrder定义的顺序,其具有优先权。
注意:在使用该注解的propOrder属性时,必须列出javaBean对象的所有属性,否则会报错
@XmlType(name="xxx",propOrder={
"xxx",
"yyy",
"zzz"
})
@XmlRootElement
用于类级别的注解,对应xml的根元素。常与@XmlType和@XmlAccessorType一起用。
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Liwl{
}
@XmlElement
将java对象的属性,映射为xml节点。在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。
@XmlElement(name="Address")
privage String yourAddress
@XmlElementWrapper
@XmlAttribute
把java对象的属性,映射为xml的属性,并可通过name属性,为生成的xml属性指定别名。
@XmlAttribute(name="Country")
private String state;
@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或@XmlAttriute注解,这些成员变量依然可以映射到xml文件
- 虽然@XmlAccessorType为@XmlAccessType.NONE,但是在java类的私有属性加上@XmlAttribute和@XmlElement注解后,这些私有成员会映射成xml元素
@XmlAccessorOrder
该注解对java对象生成的xml元素排序,它有两个属性值:
- AccessorOrder.ALPHABETICAL 对生成的xml元素按照字母书写顺序排序
- XmlAccessOrder.UNDEFINED 不排序
@XmlTransient
该注解用于标注由java对象映射xml时,忽略被此注解标注的属性。即在生成的文件中不出现此元素
@XmlJavaTypeAdapter
常用于在转换比较复杂的对象时,如map类型或者格式化日期等,使用此注解,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。
@XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类