java中bean和xml相互转换
简介
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。
bean转xml
java在1.6之后内置了jaxb的实现,但在11中已经去除了,需要我们手动导入依赖
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
代码实现
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
User user = new User();
user.setUserId("1");
user.setUsername("lisi");
user.setPassword("123456");
user.setAddress(new Address("山东", "济南"));
user.setHobbyList(Arrays.asList(new Hobby("游泳"), new Hobby("跑步")));
System.out.println(bean2Xml(user));
}
/**
* 将javabean转换成xml字符串
*/
private static String bean2Xml(Object obj) throws Exception {
//获取上下文
final JAXBContext context = JAXBContext.newInstance(obj.getClass());
//创建一个将bean序列化成xml的对象
Marshaller marshaller = context.createMarshaller();
//格式化输出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//设置编码
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
StringWriter writer = new StringWriter();
//序列化
marshaller.marshal(obj, writer);
return writer.toString();
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"username", "password", "address", "hobbyList"})
@XmlRootElement(name = "User")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@XmlAttribute(name = "userId")
private String userId;
@XmlElement(name = "username")
private String username;
@XmlElement(name = "password")
private String password;
@XmlElement(name = "address")
private Address address;
@XmlElement(name = "hobby")
@XmlElementWrapper(name = "hobbyList")
private List<Hobby> hobbyList;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "address")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "hobby")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}
输出结果为
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<User userId="1">
<username>lisi</username>
<password>123456</password>
<address>
<province>山东</province>
<city>济南</city>
</address>
<hobbyList>
<hobby>
<name>游泳</name>
</hobby>
<hobby>
<name>跑步</name>
</hobby>
</hobbyList>
</User>
- @XmlAccessorType,必填,FIELD表示每一个非静态的,非瞬时的(@XmlTransient标注)属性
- @XmlType,非必填,控制属性的排序
- @XmlRootElement,必填,表示xml的根元素
- @XmlAttribute,表示xml属性
- @XmlElement,表示xml元素
- @XmlElementWrapper,表示一个数组或集合的包装器
xml转bean
import java.io.StringReader;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<User userId=\"1\">\n"
+ " <username>lisi</username>\n"
+ " <password>123456</password>\n"
+ " <address>\n"
+ " <province>山东</province>\n"
+ " <city>济南</city>\n"
+ " </address>\n"
+ " <hobbyList>\n"
+ " <hobby>\n"
+ " <name>游泳</name>\n"
+ " </hobby>\n"
+ " <hobby>\n"
+ " <name>跑步</name>\n"
+ " </hobby>\n"
+ " </hobbyList>\n"
+ "</User>";
System.out.println(xml2Bean(xml, User.class));
}
/**
* 将xml字符串转换成javabean
*/
private static <T> T xml2Bean(String xml, Class<T> clazz) throws Exception {
//获取上下文
final JAXBContext context = JAXBContext.newInstance(clazz);
//创建一个xml转换成bean的对象
Unmarshaller unmarshaller = context.createUnmarshaller();
//反序列化
return clazz.cast(unmarshaller.unmarshal(new StringReader(xml)));
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "User")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@XmlAttribute(name = "userId")
private String userId;
@XmlElement(name = "username")
private String username;
@XmlElement(name = "password")
private String password;
@XmlElement(name = "address")
private Address address;
@XmlElement(name = "hobby")
@XmlElementWrapper(name = "hobbyList")
private List<Hobby> hobbyList;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "address")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "hobby")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}
使用jackson将bean转xml
引入依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.3</version>
</dependency>
代码实现
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Arrays;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
User user = new User();
user.setUserId("1");
user.setUsername("lisi");
user.setPassword("123456");
user.setAddress(new Address("山东", "济南"));
user.setHobbyList(Arrays.asList(new Hobby("游泳"), new Hobby("跑步")));
System.out.println(bean2Xml(user));
}
/**
* 将javabean转换成xml字符串
*/
private static String bean2Xml(Object obj) throws Exception {
XmlMapper mapper = new XmlMapper();
//格式化输出
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}
@JacksonXmlRootElement(localName = "user")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@JacksonXmlProperty(isAttribute = true)
private String userId;
@JacksonXmlProperty(localName = "userName")
private String username;
private String password;
private Address address;
@JacksonXmlProperty(localName = "hobby")
@JacksonXmlElementWrapper(localName = "hobbyList")
private List<Hobby> hobbyList;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}
输出结果同上
- @JacksonXmlRootElement,非必填,类似jaxb的@XmlRootElement
- @JacksonXmlProperty,isAttribute表示是否为属性,为jaxb的@XmlElement和@XmlAttribute的组合
- @JacksonXmlElementWrapper,子元素包装器,类似jaxb的@XmlElementWrapper
使用jackson将xml转bean
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
String xml = "<user userId=\"1\">\n"
+ " <password>123456</password>\n"
+ " <address>\n"
+ " <province>山东</province>\n"
+ " <city>济南</city>\n"
+ " </address>\n"
+ " <userName>lisi</userName>\n"
+ " <hobbyList>\n"
+ " <hobby>\n"
+ " <name>游泳</name>\n"
+ " </hobby>\n"
+ " <hobby>\n"
+ " <name>跑步</name>\n"
+ " </hobby>\n"
+ " </hobbyList>\n"
+ "</user>";
System.out.println(xml2Bean(xml, User.class));
}
/**
* 将xml字符串转换成javabean
*/
private static <T> T xml2Bean(String xml, Class<T> clazz) throws Exception {
XmlMapper mapper = new XmlMapper();
return mapper.readValue(xml, clazz);
}
@JacksonXmlRootElement(localName = "user")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@JacksonXmlProperty(isAttribute = true)
private String userId;
@JacksonXmlProperty(localName = "userName")
private String username;
private String password;
private Address address;
@JacksonXmlProperty(localName = "hobby")
@JacksonXmlElementWrapper(localName = "hobbyList")
private List<Hobby> hobbyList;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}