工具类MarshallAble.java
package com.example.demo.jaxb;
import org.springframework.util.ClassUtils;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
/**
* Xml Bean转换基础类
*
*/
public abstract class MarshallAble{
public String marshallToString() throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(ClassUtils.getUserClass(childClass()));
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
StringWriter writer = new StringWriter();
marshaller.marshal(this, writer);
return writer.toString().replace(" standalone=\"yes\"", "");
}
public static <T> T unMarshallFromString(String xmlStr, Class<T> clazz) throws JAXBException{
JAXBContext context = JAXBContext.newInstance(ClassUtils.getUserClass(clazz));
// 进行将Xml转成对象的核心接口
Unmarshaller unmarshaller = context.createUnmarshaller();
Reader reader = new StringReader(xmlStr);
return (T) unmarshaller.unmarshal(reader);
}
public abstract Class<?> childClass();
}
Java对象Person.java
package com.example.demo.jaxb;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.xml.bind.annotation.*;
import java.util.List;
/**
* 创建类
*
*/
@Data
@Builder
@XmlRootElement(name = "body")
@XmlAccessorType(XmlAccessType.FIELD)
@EqualsAndHashCode(callSuper=false)
@XmlSeeAlso({ Person.FriendsList.class})
public class Person extends MarshallAble {
@XmlElement
private String name;
@XmlElement
private String age;
@XmlElementWrapper(name = "lists")
@XmlElement(name = "list")
private List<FriendsList> lists;
public Person(String name, String age,List list) {
this.name = name;
this.age = age;
this.lists = list;
}
public Person() {
}
@Data
@Builder
public static class FriendsList {
private String name; // name
private String age; // age
public FriendsList(String name, String age) {
this.name = name;
this.age = age;
}
public FriendsList() {
}
}
@Override
public Class<?> childClass() {
return this.getClass();
}
}
测试类 JaxbDemo.java
package com.example.demo.jaxb;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONValue;
import javax.xml.bind.JAXBException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class JaxbDemo {
public static void main(String[] args) {
Person.FriendsList friend1 = new Person.FriendsList("John","23");
Person.FriendsList friend2 = new Person.FriendsList("Martin","25");
List<Person.FriendsList> list = new ArrayList<>();
list.add(friend1);
list.add(friend2);
Person person = new Person("Johnny","25",list);
try {
String resp = person.marshallToString();
log.info("XML to String:{}",resp);
Person personObj = MarshallAble.unMarshallFromString(resp,Person.class);
log.info("String to XML:{}",JSONValue.toJSONString(personObj));
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
执行结果是:包含内部类的解析和转化
Connected to the target VM, address: '127.0.0.1:63937', transport: 'socket'
02:03:56.613 [main] INFO com.example.demo.jaxb.JaxbDemo - XML to String:<?xml version="1.0" encoding="GBK"?><body><name>Johnny</name><age>25</age><lists><list><age>23</age><name>John</name></list><list><age>25</age><name>Martin</name></list></lists></body>
02:03:57.360 [main] INFO com.example.demo.jaxb.JaxbDemo - String to XML:{"lists":[{"name":"John","age":"23"},{"name":"Martin","age":"25"}],"name":"Johnny","age":"25"}
Disconnected from the target VM, address: '127.0.0.1:63937', transport: 'socket'
注意:JAXB 转换对象必须拥有无参数构造器(默认存在,如果被覆盖,需要显示指定)
Marshaller有五个参数可以配置:常用的三种
jaxb.encoding 是否指定输出编码
jaxb.formatted.output 是否格式化,即换行和缩进
jaxb.fragment 是否生成文档级事件
/**
* The name of the property used to specify the output encoding in
* the marshalled XML data.
*/
public static final String JAXB_ENCODING =
"jaxb.encoding";
/**
* The name of the property used to specify whether or not the marshalled
* XML data is formatted with linefeeds and indentation.
*/
public static final String JAXB_FORMATTED_OUTPUT =
"jaxb.formatted.output";
/**
* The name of the property used to specify the xsi:schemaLocation
* attribute value to place in the marshalled XML output.
*/
public static final String JAXB_SCHEMA_LOCATION =
"jaxb.schemaLocation";
/**
* The name of the property used to specify the
* xsi:noNamespaceSchemaLocation attribute value to place in the marshalled
* XML output.
*/
public static final String JAXB_NO_NAMESPACE_SCHEMA_LOCATION =
"jaxb.noNamespaceSchemaLocation";
/**
* The name of the property used to specify whether or not the marshaller
* will generate document level events (ie calling startDocument or endDocument).
*/
public static final String JAXB_FRAGMENT =
"jaxb.fragment";
优秀参考名单: