将含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
相关产品推荐
相关产品推荐

