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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:36:23