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

Spring Boot Rest API中Jackson XML序列化Employee标签包裹异常问题求助

Spring Boot Rest API中Jackson XML序列化Employee标签包裹异常问题求助

各位大佬好,我最近在做Spring Boot的Rest API,需要返回特定格式的XML响应,但遇到了序列化的问题:所有员工的数据都被塞进了同一个<employee>标签里,而不是每个员工对应独立的<employee>标签。我已经折腾好一阵了,还是没找到问题所在,麻烦帮忙看看哪里出错了🥺


我的实体类代码

EmployeesRoot.java

@JacksonXmlRootElement(localName = "employees", namespace = "https://www.google.com")
public class EmployeesRoot {
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(namespace = "https://www.google.com", localName = "employee")
    private List<Employee> employee;

    public List<Employee> getEmployee() {
        return employee;
    }

    public void setEmployee(List<Employee> employee) {
        this.employee = employee;
    }
}

Employee.java

public class Employee {
    @JacksonXmlProperty(namespace = "https://www.google.com", localName = "empId")
    private String empId;
    
    @JacksonXmlProperty(namespace = "https://www.example.com", localName = "employee")
    private EmployeeInfo employeeDetails;

    // Getters and Setters
}

EmployeeInfo.java

public class EmployeeInfo {
    @JacksonXmlProperty(namespace = "https://www.example.com", localName = "name")
    private String name;
    
    @JacksonXmlProperty(namespace = "https://www.example.com", localName = "gender")
    private String gender;

    // Getters and Setters
}

自定义序列化器代码

为了处理命名空间,我写了一个自定义序列化器:

import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.core.JsonGenerator;
import javax.xml.stream.XMLStreamException;
import java.io.IOException;

public class EmployeeRootSerializer extends StdSerializer<EmployeesRoot> {
    public EmployeeRootSerializer() {
        super(EmployeesRoot.class);
    }

    @Override
    public void serialize(EmployeesRoot value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        ToXmlGenerator xmlGen = (ToXmlGenerator) gen;
        xmlGen.writeStartObject();
        try {
            xmlGen.getStaxWriter().writeNamespace("", "https://www.google.com");
            xmlGen.getStaxWriter().writeNamespace("employee", "https://www.example.com");
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
        xmlGen.writeObjectField("employee", value.getEmployee());
        xmlGen.writeEndObject();
    }
}

控制器中的序列化逻辑

// 构建员工数据
EmployeesRoot root = new EmployeesRoot();
List<Employee> employeeList = new ArrayList<>();
for(SomeDTO obj : someDtoElements) {
    Employee employee = new Employee();
    employee.setEmpId(obj.getId());
    EmployeeInfo empInfo = new EmployeeInfo();
    empInfo.setName(obj.getName());
    empInfo.setGender(obj.getGender());
    employee.setEmployeeDetails(empInfo);
    employeeList.add(employee);
}
root.setEmployee(employeeList);

// 配置XML序列化
SimpleModule module = new SimpleModule();
module.addSerializer(EmployeesRoot.class, new EmployeeRootSerializer());
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setDefaultUseWrapper(false);
xmlMapper.registerModule(module);

// 生成并返回XML响应
return xmlMapper.writeValueAsString(root);

预期的XML输出

<employees xmlns = "https://www.google.com" xmlns:employee = "https://www.example.com">
    <employee>
        <empId>1</empId>
        <employee:employee>
            <employee:name>Hi</employee:name>
            <employee:gender>Male</employee:gender>
        </employee:employee>
    </employee>
    <employee>
        <empId>2</empId>
        <employee:employee>
            <employee:name>Hello</employee:name>
            <employee:gender>Male</employee:gender>
        </employee:employee>
    </employee>
</employees>

实际得到的XML输出

<employees xmlns = "https://www.google.com" xmlns:employee = "https://www.example.com">
    <employee>
        <empId>1</empId>
        <employee:employee>
            <employee:name>Hi</employee:name>
            <employee:gender>Male</employee:gender>
        </employee:employee>
        <empId>2</empId>
        <employee:employee>
            <employee:name>Hello</employee:name>
            <employee:gender>Male</employee:gender>
        </employee:employee>
    </employee>
</employees>

环境信息

  • Spring Boot版本:2.7.18
  • jackson-dataformat-xml版本:2.13.5

核心疑问

我发现如果不用自定义序列化器,虽然命名空间格式不对,但每个Employee会生成独立的<employee>标签;但加上自定义序列化器处理命名空间后,所有员工的内容都被塞进了同一个<employee>标签里。我怀疑是xmlGen.writeObjectField("employee", value.getEmployee());这行代码的问题,但不知道怎么改才能兼顾命名空间和独立标签的需求。

麻烦各位大佬帮忙看看,我到底哪里漏了或者写错了?


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 10:03:09