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

将含HashMap的POJO转换为XML:自定义节点结构实现问询

JAXB XML序列化自定义结构解决方案

原问题场景

原Java类

@XmlRootElement( name = "counters" )
public class Counter {
    private Map<String, Integer> counter;
    
    public Counter(){}
     
    @XmlElement( name = "counter" )
    public Map<String, Integer> getCounter() {
        return counter;
    }
    
    public void setCounter(Map<String, Integer> counter) {
        this.counter = counter;
    }
}

当前生成的XML结构

<counters>
    <counter>
        <entry>
            <key>admin</key>
            <value>10</value>
        </entry>
        <entry>
            <key>user</key>
            <value>5</value>
        </entry>
    </counter>
</counters>

期望的XML结构

<counters>
    <counter>
        <user>admin</user>
        <number>10</number>
    </counter>
    <counter>
        <user>user</user>
        <number>5</number>
    </counter>
</counters>

需要实现:将<entry>节点重命名为<counter>,<key>改为<user>,<value>改为<number>。


解决方案

直接用HashMap配合JAXB原生注解无法实现该需求,因为JAXB对Map的序列化逻辑是固定生成<entry>节点包裹<key>和<value>,无法灵活修改节点层级与名称。必须通过调整Counter类的结构来达成目标,具体步骤如下:

1. 定义自定义实体类封装计数信息

创建UserCounter类,单独封装每个用户的名称和计数,通过注解指定XML节点名称:

public class UserCounter {
    private String user;
    private Integer number;

    public UserCounter() {}

    public UserCounter(String user, Integer number) {
        this.user = user;
        this.number = number;
    }

    @XmlElement(name = "user")
    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    @XmlElement(name = "number")
    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }
}

2. 修改Counter类结构

将原来的Map<String, Integer>替换为List<UserCounter>,通过注解配置根节点与子节点名称:

@XmlRootElement(name = "counters")
@XmlAccessorType(XmlAccessType.FIELD)
public class Counter {
    @XmlElement(name = "counter")
    private List<UserCounter> counters;

    public Counter() {}

    public List<UserCounter> getCounters() {
        return counters;
    }

    public void setCounters(List<UserCounter> counters) {
        this.counters = counters;
    }

    // 可选:添加从Map转换为List的工具方法,兼容原有逻辑
    public void setCounterMap(Map<String, Integer> counterMap) {
        this.counters = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : counterMap.entrySet()) {
            this.counters.add(new UserCounter(entry.getKey(), entry.getValue()));
        }
    }
}

效果验证

修改后序列化Counter对象,生成的XML将完全符合期望的结构:

<counters>
    <counter>
        <user>admin</user>
        <number>10</number>
    </counter>
    <counter>
        <user>user</user>
        <number>5</number>
    </counter>
</counters>

内容的提问来源于stack exchange,提问作者Ubuntu Learner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:15:37