You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:01:05