Jackson XML反序列化报错:Unrecognized field 'faction'求助
Jackson XML反序列化与序列化问题解决
问题场景
尝试反序列化以下XML:
<fightrules> <fightrule id="1" owner="player" name="Переопределение разрешения открывать огонь #1"/> <fightrule id="2" owner="player" name="Ксеноны"> <setting faction="xenon" civilian="engage"/> </fightrule> </fightrules>
使用的Java实体类定义:
@Data public class Fightrules { public List<Fightrule> fightrule; @Data @JsonAutoDetect public static class Fightrule { public int id; public String owner; public String name; @JacksonXmlElementWrapper(useWrapping = false) public List<Setting> setting; } } @Data public class Setting { @JacksonXmlProperty(isAttribute = true) public String faction; @JacksonXmlProperty(isAttribute = true) public String civilian; }
遇到的问题:
- 反序列化抛出异常:
Unrecognized field "faction" (class Fightrules$Fightrule), not marked as ignorable,Jackson未识别嵌套的Setting列表,反而试图将faction映射到Fightrule类。 - 序列化生成的XML结构不符合预期,出现多余的嵌套包裹层:
<Fightrules> <fightrule> <fightrule id="2" owner="player" name="Ксеноны"> <setting> <setting faction="xenon" civilian="engage"/></setting> </fightrule> <fightrule id="1" owner="player" name="Переопределение разрешения открывать огонь #1"/></fightrule> </Fightrules>
解决方案
问题根源在于缺少关键Jackson XML注解,导致节点映射逻辑混乱。修正后的实体类如下:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import lombok.Data; @Data @JacksonXmlRootElement(localName = "fightrules") // 指定根节点名称为小写的fightrules public class Fightrules { @JacksonXmlElementWrapper(useWrapping = false) // 禁用列表外层的包裹节点 @JacksonXmlProperty(localName = "fightrule") // 指定列表元素的XML节点名称 public List<Fightrule> fightrule; @Data @JsonIgnoreProperties(ignoreUnknown = true) // 忽略未知字段,适配无setting节点的fightrule public static class Fightrule { @JacksonXmlProperty(isAttribute = true) // 标记为XML属性 public int id; @JacksonXmlProperty(isAttribute = true) public String owner; @JacksonXmlProperty(isAttribute = true) public String name; @JacksonXmlElementWrapper(useWrapping = false) @JacksonXmlProperty(localName = "setting") // 指定子元素的XML节点名称 public List<Setting> setting; } } @Data public class Setting { @JacksonXmlProperty(isAttribute = true) public String faction; @JacksonXmlProperty(isAttribute = true) public String civilian; }
修正说明
@JacksonXmlRootElement:指定根节点名称,解决序列化时根节点首字母大写的问题。@JacksonXmlProperty(localName = "..."):明确指定每个字段对应的XML元素/属性名称,避免Jackson默认的命名规则干扰。@JacksonXmlProperty(isAttribute = true):将Fightrule的id、owner、name标记为XML属性,而非子元素,匹配目标XML结构。@JsonIgnoreProperties(ignoreUnknown = true):忽略反序列化时的未知字段,适配部分fightrule没有setting节点的场景,避免报错。@JacksonXmlElementWrapper(useWrapping = false):禁用列表的外层包裹节点,确保序列化后直接生成多个<fightrule>和<setting>节点,符合预期结构。
内容的提问来源于stack exchange,提问作者BANTYC
相关产品推荐
相关产品推荐

