JAXB是Java标准API,用于Java类与XML双向自动绑定;Java 9起移除,需手动引入jakarta.xml.bind依赖;核心注解包括@XmlRootElement、@XmlElement等;使用JAXBContext、Marshaller和Unmarshaller完成序列化与反序列化。

DocumentBuilder,JAXB 能靠注解把对象“映射”成 XML,也能把 XML 字符串反向还原为对象——前提是类结构合理、注解到位、依赖齐备。
如何添加 JAXB 运行时依赖(Java 9+ 必做)
Java 9+ 中 javax.xml.bind 包已不在默认 classpath,必须显式添加实现:
- Maven 项目需在
pom.xml中加入:jakarta.xml.bind jakarta.xml.bind-api 4.0.0 org.glassfish.jaxb jaxb-runtime 4.0.4 - 注意包名已从
javax.xml.bind升级为jakarta.xml.bind(Java EE → Jakarta EE 迁移结果) - 若用老代码(含
javax.*导包),要么加jakarta.xml.bind:jakarta.xml.bind-api的javax.xml.bind兼容桥接版,要么批量替换导入(推荐后者)
@XmlRootElement 和其他关键注解怎么用
JAXB 靠注解驱动绑定逻辑。最常用的是:
-
@XmlRootElement:标记类可作为 XML 根元素(否则JAXBContext.newInstance(YourClass.class)会抛IllegalArgumentException) -
@XmlElement:控制字段/属性在 XML 中的标签名、是否必需(required = true)、是否 nillable -
@XmlAttribute:将字段序列化为 XML 属性而非子元素 -
@XmlAccessorType(XmlAccessType.FIELD):让 JAXB 直接访问字段(避免写 getter/setter),常配在类上
示例类:
import jakarta.xml.bind.annotation.*;
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
@XmlElement(name = "name")
private String userName;
@XmlAttribute(name = "id")
private int userId;
@XmlElement(name = "email")
private String email;
}
用 JAXBContext + Marshaller / Unmarshaller 做转换
核心流程固定:获取上下文 → 创建编组器/解组器 → 执行操作。常见错误包括未设编码、忽略异常、未关闭流。
立即学习“Java免费学习笔记(深入)”;
- 序列化(Java → XML):
JAXBContext context = JAXBContext.newInstance(User.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.marshal(new User(), System.out);
- 反序列化(XML → Java):
Unmarshaller unmarshaller = context.createUnmarshaller(); User user = (User) unmarshaller.unmarshal(new StringReader(" "));Alice a@b.c - 若 XML 含命名空间,需提前在类上用
@XmlSchema或@XmlNs声明,否则解组可能静默失败或字段为空 - 对大文件慎用
unmarshal(InputStream)—— 若流未按 UTF-8 编码读取,中文会乱码;建议包装为InputStreamReader并指定 charset
常见报错和绕过方式
实际用时高频出错点集中在环境、注解、XML 格式三方面:
-
ClassNotFoundException: javax.xml.bind.JAXBContext→ 确认 JDK 版本并添加 Jakarta JAXB 依赖(非旧 javax 版) -
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"user")→ 检查 XML 根元素名是否与@XmlRootElement(name = "...")一致;若 XML 有默认命名空间,类上要加@XmlRootElement(namespace = "http://example.com") - 字段值为 null 但 XML 中没对应标签 → 默认跳过;如需输出
,得加@XmlElement(nillable = true)并设置marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, ...) - 集合字段(如
List)未生效 → 必须用@XmlElement修饰该字段,且不能只靠泛型;JAXB 不识别ArrayList,推荐包装为独立类或用@XmlElementWrapper










