如何使用Jackson Faster XML将XML属性映射为Java类属性
实现方案
Jackson FasterXML默认按XML节点和Java属性的一一对应关系做映射,你给出的XML用details节点下的通用element条目存键值对,和Student类的扁平字段结构不匹配,无法直接通过基础注解完成映射,需要通过自定义反序列化逻辑实现,步骤如下:
- 首先确保项目已引入
jackson-dataformat-xml核心依赖 - 给目标Java类绑定自定义反序列化器,匹配XML根节点
- 在自定义反序列化逻辑中遍历
details下的所有element节点,提取key/value属性,匹配对应字段赋值
1. 定义Student实体类
给类加XML根节点注解,同时绑定自定义反序列化器,补全必要的构造方法、getter/setter:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; @JacksonXmlRootElement(localName = "student") @JsonDeserialize(using = StudentDeserializer.class) public class Student { private String firstName; private String lastName; public Student() {} public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
2. 实现自定义反序列化器
遍历XML节点结构,定位到details下的所有element条目,按key值给Student对象的对应属性赋值:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; public class StudentDeserializer extends JsonDeserializer<Student> { @Override public Student deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { Student student = new Student(); // 遍历student节点下的所有内容 while (p.nextToken() != JsonToken.END_OBJECT) { String nodeName = p.currentName(); if ("details".equals(nodeName)) { p.nextToken(); // 进入details节点内部 // 遍历details下的所有节点 while (p.nextToken() != JsonToken.END_OBJECT) { if ("element".equals(p.currentName())) { // 读取element节点的key、value属性 String fieldKey = p.getAttributeValue(null, "key"); String fieldValue = p.getAttributeValue(null, "value"); // 匹配字段赋值 switch (fieldKey) { case "firstName" -> student.setFirstName(fieldValue); case "lastName" -> student.setLastName(fieldValue); // 后续新增字段直接在这里加case即可 } p.nextToken(); // 跳过当前element节点的闭合标记 } } } } return student; } }
3. 执行解析验证
初始化XmlMapper对象,直接传入XML字符串解析即可:
import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class ParseDemo { public static void main(String[] args) throws Exception { String xmlContent = """ <student> <details> <element key="firstName" value="John" /> <element key="lastName" value="Doe" /> </details> </student> """; XmlMapper xmlMapper = new XmlMapper(); Student student = xmlMapper.readValue(xmlContent, Student.class); // 输出结果:firstName=John, lastName=Doe System.out.printf("firstName=%s, lastName=%s%n", student.getFirstName(), student.getLastName()); } }
注意:不要尝试仅用
@JacksonXmlProperty这类基础注解实现映射,这类注解只能处理节点名/属性名和Java字段固定对应的场景,无法适配你给出的动态键值对列表结构。
如果后续需要扩展字段,只需要在Student类新增对应属性,同时在反序列化器的switch分支中增加对应key的赋值逻辑即可,不需要调整整体解析流程。
内容的提问来源于stack exchange,提问作者Ullas
相关产品推荐
相关产品推荐

