jackson-dataformat-xml反序列化XML时JsonProperty required属性失效
问题描述
使用Jackson框架jackson-dataformat-xml模块时遇到必填属性校验不一致问题,具体表现如下:
- 解析JSON场景:标注了
@JsonProperty(required = true)的属性缺失时,框架会正常抛出提示为Missing required creator property的MismatchedInputException异常,符合预期。 - 解析XML场景:即使必填属性/XML元素缺失,框架也不会抛出校验异常,手动配置
DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES参数也没有效果。 - 版本差异:该校验逻辑在
jackson-dataformat-xml 2.11.4版本可正常生效,从2.12.0版本开始失效。 - 现有配置:实体类构造方法已添加
@JsonCreator注解,对应必填参数也标注了@JsonProperty(required = true),不确定是否需要使用其他专属注解标记XML必填元素。
示例代码
实体类定义
@JsonRootName(value = "bar") public class Bar { @JsonProperty(value = "foo", required = true) private int foo; public Bar() {} @JsonCreator public Bar(@JsonProperty(value = "foo", required = true) final int foo) { this.foo = foo; } public int getFoo() { return this.foo; } @Override public int hashCode() { return Objects.hash(this.foo); } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!(obj instanceof Bar)) { return false; } final Bar other = (Bar) obj; return this.foo == other.foo; } @Override public String toString() { return "Bar: " + Objects.toString(this.foo); } }
JSON反序列化测试(符合预期)
传入空JSON对象缺失foo属性时,用例可正常抛出预期异常:
@Test(expected = JsonProcessingException.class) public void deserializeJson() throws Exception { final ObjectMapper jsonMapper = new ObjectMapper(); final Bar expected = new Bar(123); final Bar actual = jsonMapper.readValue("{}", Bar.class); // missing property foo in JSON string }
XML反序列化测试(不符合预期)
传入空根节点缺失foo子元素时,用例不会抛出预期异常,校验失效:
@Test(expected = JsonProcessingException.class) public void deserializeXml() throws Exception { final XmlMapper xmlMapper = new XmlMapper(); xmlMapper.configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, true); final Bar expected = new Bar(123); final Bar actual = xmlMapper.readValue("<bar></bar>", Bar.class); // missing element foo in XML string Assert.fail("Expected com.fasterxml.jackson.databind.exc.MismatchedInputException: Missing required creator property 'foo' (index 0)"); }
问题原因与解决方案
这是2.12版本起jackson-dataformat-xml模块的默认行为变更导致的,不需要换用XML专属的必填标记注解,按使用的版本配置对应参数即可修复:
- 2.12.x~2.14.x版本:该版本区间的XML解析器新增了*幻影属性(phantom property)*处理逻辑,缺失的XML节点会被默认映射为空值节点,直接跳过必填校验,且这个逻辑不受
DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES参数控制。需要额外开启FromXmlParser.Feature.FAIL_ON_MISSING_PHANTOM_PROPERTIES配置,推荐用builder方式初始化XmlMapper:
XmlMapper xmlMapper = XmlMapper.builder() .enable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES) .enable(FromXmlParser.Feature.FAIL_ON_MISSING_PHANTOM_PROPERTIES) .build();
- 2.15.x及以上版本:官方已经将
FAIL_ON_MISSING_PHANTOM_PROPERTIES调整为默认开启状态,只需要保留FAIL_ON_MISSING_CREATOR_PROPERTIES的开启配置,即可和JSON解析逻辑一致,正常触发必填属性缺失的异常。
排错提示:示例实体类同时定义了无参构造和标记了
@JsonCreator的全参构造,部分小版本存在构造方法优先级判断问题,如果配置完上述参数后校验仍不生效,可以给无参构造添加@JsonIgnore注解,强制框架走带参构造实例化对象,就能正常触发构造参数的必填校验。
内容的提问来源于stack exchange,提问作者Johan De Schutter
相关产品推荐
相关产品推荐

