并能将Java对象树的内容重新写到XML实例文档。
两个个JAXB的实体类的例子:
//例子2
import java.util.ArrayList;
import java.util.List;
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;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="", propOrder={"log"})
@XmlRootElement(name="info")
public class LogReportMsg
{
@XmlElement(required=true)
protected List log;
@XmlAttribute
protected String id;
@XmlAttribute
protected String type;
public List getLog()
{
if (this.log == null) {
this.log = new ArrayList();
}
return this.log;
}
public String getId()
{
return this.id;
}
public void setId(String value)
{
this.id = value;
}
public String getType()
{
if (this.type == null) {
return "login_info";
}
return this.type;
}
public void setType(String value)
{
this.type = value;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="")
public static class Log
{
@XmlAttribute
protected String account;
@XmlAttribute
protected String accountType;
public String getAccount()
{
return this.account;
}
public void setAccount(String value)
{
this.account = value;
}
public String getAccountType()
{
if (this.accountType == null) {
return "2";
}
return this.accountType;
}
public void setAccountType(String value)
{
this.accountType = value;
}
}
}
//模版
//例子2
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;
/**
* Java class for anonymous complex type.
*
*
The following schema fragment specifies the expected content contained within this class.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"alarmType",
"alarmTime",
"alarmDesc"
})
@XmlRootElement(name = "info")
public class AlarmReqMsg {
@XmlElement(required = true)
protected String alarmType;
@XmlElement(required = true)
protected String alarmTime;
@XmlElement(required = true)
protected String alarmDesc;
@XmlAttribute(required = true)
protected String id;
@XmlAttribute(required = true)
protected String type;
//自动生成的 set/get 方法
}
//模版
注解介绍
1) @XmlType
2) @XmlElement
3) @XmlRootElement
4) @XmlAttribute
5) @XmlAccessorType
6) @XmlAccessorOrder (不常用)
7) @XmlTransient (不常用)
8) @XmlJavaTypeAdapter (不常用)
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
// 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);
}
2 使用举例
例子1:
package test;
public class Classroom {
private int id;
private String name;
private int grade;
public Classroom() {
super();
}
public Classroom(int id, String name, int grade) {
super();
this.id = id;
this.name = name;
this.grade = grade;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
package test;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Student {
private int id;
private String name;
private int age;
private Classroom classroom;
public Student() {
super();
}
public Student(int id, String name, int age, Classroom classroom) {
super();
this.id = id;
this.name = name;
this.age = age;
this.classroom = classroom;
}
public int getId() {
return id;
}
public void setId(int 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;
}
public Classroom getClassroom() {
return classroom;
}
public void setClassroom(Classroom classroom) {
this.classroom = classroom;
}
}
package test;
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 Test {
public static void beanToXML(){
Classroom classroom = new Classroom(1, "软件工程", 4);
Student student = new Student(101,"张三", 22, classroom);
try {
JAXBContext context = JAXBContext.newInstance(Student.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(student, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
public static void XMLStringToBean(){
//
String xmlStr = "" +
"22 " +
"4 1 软件工程 " +
"101 张三 ";
try {
JAXBContext context = JAXBContext.newInstance(Student.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Student student = (Student)unmarshaller.unmarshal(new StringReader(xmlStr));
System.out.println(student.getAge());
System.out.println(student.getClassroom().getName());
} catch (JAXBException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
beanToXML();
// XMLStringToBean();
}
}
结果:
生成文件为
22
4
1
软件工程
101
张三
例子2
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MessageHelper {
final private Logger LOGGER = LoggerFactory.getLogger(getClass());
private Map, JAXBContext> contextMap = new HashMap, JAXBContext>();
private static MessageHelper instance;
private MessageHelper(){
InputStream in =getClass().getClassLoader().getResourceAsStream("msgClasses"); //将需要处理的类放在这里,带包名
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line ="";
while(true){
try {
line = reader.readLine();
} catch (IOException e) {
LOGGER.error("read msgClasses error",e);
}
if(line == null){
break;
}else{
String className = line.trim();
Class extends Object> clazz;
try {
clazz = Class.forName(className);
JAXBContext context = JAXBContext.newInstance(clazz);
contextMap.put(clazz, context);
} catch (ClassNotFoundException e) {
LOGGER.error("ClassNotFound",e);
} catch (JAXBException e) {
LOGGER.error("init jaxbContext error className is"+className,e);
}
}
}
}
public static MessageHelper getInstance(){
if(instance == null){
synchronized(MessageHelper.class){
if(instance == null){
instance = new MessageHelper();
}
}
}
return instance;
}
@SuppressWarnings("unchecked")
public T unmarshal(String str,Class clazz){
T result = null;
StringReader reader = new StringReader(str); //字符读
try {
Unmarshaller unmarshaller = contextMap.get(clazz).createUnmarshaller();
result = (T) unmarshaller.unmarshal(reader);
} catch (JAXBException e) {
LOGGER.error("unmarshal xml error",e);
}
return result;
}
public String marshal(Object obj,Class clazz) {
StringWriter writer = new StringWriter(); //字符串写
writer.write("\n");
try {
Marshaller marshaller = contextMap.get(clazz).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(obj, writer);
} catch (JAXBException e) {
LOGGER.error("marshal xml error",e);
}
return writer.toString();
}
}
//调用
MessageHelper.getInstance().marshal(AA, AA.class)
MessageHelper.getInstance().unmarshal(sb.toString(), AA.class);