在Java开发的实际场景中,XML作为常用的数据交换格式,经常需要和POJO对象进行相互转换,比如接口报文解析、配置文件读取等场景都需要用到这种映射能力。目前主流的实现方案有JAXB和Jackson Xml两种,下面分别介绍它们的使用方式。

一、使用JAXB实现映射
JAXB是Java官方提供的XML绑定框架,从Java 6开始就内置在JDK中,不需要额外引入依赖,适合对依赖管控比较严格的项目。
1.1 定义POJO并添加注解
需要在POJO类上添加@XmlRootElement注解指定XML根节点,属性上通过@XmlElement指定对应的XML元素名称,如果是集合类型可以使用@XmlElementWrapper包裹外层节点。
import javax.xml.bind.annotation.*;
import java.util.List;
// 指定XML根节点名称为user
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
// 对应XML中的id元素
@XmlElement(name = "id")
private Integer id;
// 对应XML中的name元素
@XmlElement(name = "name")
private String name;
// 对应XML中的hobbies外层节点,内部包含多个hobby元素
@XmlElementWrapper(name = "hobbies")
@XmlElement(name = "hobby")
private List<String> hobbies;
// 必须提供无参构造器,JAXB反射创建对象需要
public User() {
}
public User(Integer id, String name, List<String> hobbies) {
this.id = id;
this.name = name;
this.hobbies = hobbies;
}
// getter和setter方法省略
}
1.2 XML转POJO(反序列化)
使用JAXBContext创建上下文,再通过Unmarshaller完成XML到对象的转换。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
public class JaxbDemo {
public static void main(String[] args) throws JAXBException {
String xml = "<?xml version="1.0" encoding="UTF-8"?>n" +
"<user>n" +
" <id>1</id>n" +
" <name>张三</name>n" +
" <hobbies>n" +
" <hobby>篮球</hobby>n" +
" <hobby>阅读</hobby>n" +
" </hobbies>n" +
"</user>";
// 创建JAXB上下文,指定要转换的类
JAXBContext context = JAXBContext.newInstance(User.class);
// 创建反序列化器
Unmarshaller unmarshaller = context.createUnmarshaller();
// 执行转换,将XML字符串转为User对象
User user = (User) unmarshaller.unmarshal(new StringReader(xml));
System.out.println("用户ID:" + user.getId());
System.out.println("用户名称:" + user.getName());
System.out.println("用户爱好:" + user.getHobbies());
}
}
1.3 POJO转XML(序列化)
通过Marshaller可以将POJO对象转换为XML格式字符串。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.util.Arrays;
public class JaxbDemo2 {
public static void main(String[] args) throws JAXBException {
User user = new User(2, "李四", Arrays.asList("跑步", "绘画"));
// 创建JAXB上下文
JAXBContext context = JAXBContext.newInstance(User.class);
// 创建序列化器
Marshaller marshaller = context.createMarshaller();
// 设置格式化输出,生成的XML会有缩进
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 输出到控制台,也可以输出到文件或字符串
marshaller.marshal(user, System.out);
}
}
二、使用Jackson Xml实现映射
Jackson是常用的JSON处理库,它的扩展模块Jackson Xml可以支持XML和对象的转换,使用方式和Jackson处理JSON类似,学习成本更低,功能也更灵活。
2.1 引入依赖
如果使用Maven管理项目,需要在pom.xml中添加以下依赖:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.15.2</version>
</dependency>
2.2 定义POJO并添加注解
Jackson Xml使用@JacksonXmlRootElement指定根节点,@JacksonXmlProperty指定元素属性,@JacksonXmlElementWrapper指定集合的外层包装节点。
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;
// 指定XML根节点名称为user
@JacksonXmlRootElement(localName = "user")
public class User {
// 指定对应XML元素名称为id
@JacksonXmlProperty(localName = "id")
private Integer id;
// 指定对应XML元素名称为name
@JacksonXmlProperty(localName = "name")
private String name;
// 指定外层节点名称为hobbies,内部元素名称为hobby
@JacksonXmlElementWrapper(localName = "hobbies")
@JacksonXmlProperty(localName = "hobby")
private List<String> hobbies;
public User() {
}
public User(Integer id, String name, List<String> hobbies) {
this.id = id;
this.name = name;
this.hobbies = hobbies;
}
// getter和setter方法省略
}
2.3 XML转POJO(反序列化)
使用XmlMapper对象完成转换,和Jackson处理JSON的ObjectMapper用法类似。
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.IOException;
public class JacksonXmlDemo {
public static void main(String[] args) throws IOException {
String xml = "<?xml version="1.0" encoding="UTF-8"?>n" +
"<user>n" +
" <id>3</id>n" +
" <name>王五</name>n" +
" <hobbies>n" +
" <hobby>游泳</hobby>n" +
" <hobby>唱歌</hobby>n" +
" </hobbies>n" +
"</user>";
XmlMapper xmlMapper = new XmlMapper();
// 将XML字符串转为User对象
User user = xmlMapper.readValue(xml, User.class);
System.out.println("用户ID:" + user.getId());
System.out.println("用户名称:" + user.getName());
System.out.println("用户爱好:" + user.getHobbies());
}
}
2.4 POJO转XML(序列化)
通过writeValueAsString方法可以将POJO转换为XML字符串。
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.util.Arrays;
public class JacksonXmlDemo2 {
public static void main(String[] args) throws Exception {
User user = new User(4, "赵六", Arrays.asList("书法", "围棋"));
XmlMapper xmlMapper = new XmlMapper();
// 将对象转为XML字符串
String xml = xmlMapper.writeValueAsString(user);
System.out.println(xml);
}
}
三、两种方案对比
可以通过以下维度选择适合项目的方案:
| 对比维度 | JAXB | Jackson Xml |
|---|---|---|
| 依赖情况 | JDK内置,无需额外依赖 | 需要引入第三方依赖 |
| 学习成本 | 需要了解JAXB专属注解 | 熟悉Jackson的用户学习成本极低 |
| 功能灵活性 | 功能相对固定,扩展难度较高 | 支持自定义序列化反序列化规则,扩展方便 |
| 适用场景 | 依赖管控严格、简单转换场景 | 复杂转换需求、已经使用Jackson的项目 |
四、注意事项
- POJO必须提供无参构造器,两种框架反射创建对象时都需要用到,否则会抛出实例化异常。
- XML的标签名称和POJO注解指定的名称必须一致,包括大小写,否则无法正确映射。
- 如果XML中包含命名空间,需要在注解中额外配置命名空间属性,否则会导致解析失败。
- 处理大文件XML时,建议使用流式解析方式,避免一次性加载整个XML到内存导致OOM。
JavaXML映射POJOJackson_XmlJAXB修改时间:2026-07-07 23:45:43