如何使用JAXB将两类相似XML响应反序列化为同一Java对象
问题根因
你当前配置的问题在于,Response类的commands字段仅通过@XmlElement(name = "OperationResponseCommand")绑定了单一XML节点名,JAXB解析时只会将名为OperationResponseCommand的节点映射到列表中,遇到Check响应里的CheckResponseCommand节点时会直接忽略,因此commands列表为空。
之前使用@XmlElementRefs不生效的核心原因是该注解要求映射的目标类必须配置对应名称的@XmlRootElement,且需要将目标类纳入JAXB上下文的扫描范围,实现起来比较繁琐,这种场景下用@XmlElements注解是更简单的适配方案。
修改方案
仅需要调整Response类的commands字段注解即可,Command类和JAXB工具类都无需修改:
@Data @XmlRootElement(name = "Response") @XmlAccessorType(XmlAccessType.FIELD) public class Response { @XmlElement(name = "ReturnCode") private Integer returnCode; @XmlElement(name = "ReturnMessage") private String returnMessage; @XmlElementWrapper(name = "Commands") // 配置两种节点名均映射到Command类型,统一加入commands列表 @XmlElements({ @XmlElement(name = "OperationResponseCommand", type = Command.class), @XmlElement(name = "CheckResponseCommand", type = Command.class) }) private List<Command> commands = new ArrayList<>(); }
适配效果
修改后两类响应都可以正常解析:
- 解析Operation响应时,
id字段会被正常赋值 - 解析Check响应时,
id字段由于XML中不存在对应节点,会自动赋值为null,不影响其他字段的解析 - 两种响应的命令节点都会被正常加入commands列表,不会再出现空列表的问题
内容的提问来源于stack exchange,提问作者bobanman
相关产品推荐
相关产品推荐

