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

为什么Jackson反序列化XML时子元素为null但属性解析正常?

问题原因

  1. Jackson XmlMapper默认未开启JAXB注解支持:你POJO上使用的@XmlElement、@XmlAccessorType等均为JAXB规范注解,XmlMapper默认不识别这些配置,仅按默认字段名匹配,大小写、命名空间都无法对齐导致子元素匹配失败。
  2. XML携带默认命名空间:你的TripList根节点定义了xmlns="http://hacon.de/hafas/proxy/hafas-proxy"默认命名空间,所有子节点默认归属该命名空间,POJO未配置对应命名空间映射也会触发匹配失败。

解决步骤

  • 第一步:添加Jackson JAXB注解模块依赖
    如果是Maven项目,在pom.xml中添加对应依赖(版本和你现有Jackson版本保持一致即可):
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
    <version>你的Jackson版本号</version>
</dependency>
  • 第二步:修改反序列化方法,注册JAXB模块
    修改后的deserialize方法如下:
public <T> T deserialize(String input, Class<T> type) throws JsonProcessingException {
    XmlMapper mapper = XmlMapper.builder()
        // 注册JAXB注解支持模块,识别@XmlElement等注解
        .addModule(new JaxbAnnotationModule())
        // 开启XML命名空间感知
        .enable(FromXmlParser.Feature.PROCESS_XML_NAMESPACES)
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .build();
    return mapper.readValue(input, type);
}

如果只是临时验证问题不想配置命名空间,可将enable(FromXmlParser.Feature.PROCESS_XML_NAMESPACES)改为disable(FromXmlParser.Feature.PROCESS_XML_NAMESPACES),即可忽略命名空间差异直接按标签名匹配。

  • 第三步:补全POJO命名空间配置
    两种配置方式二选一即可:
    方案1:单独给每个@XmlElement补充命名空间属性,同时给TripList添加@XmlRootElement注解:

    // 补全根节点注解
    @XmlRootElement(name = "TripList", namespace = "http://hacon.de/hafas/proxy/hafas-proxy")
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "TripList", propOrder = {
        "trip",
        "pricing",
        "sotContext"
    })
    public class TripList extends CommonResponseType {
        // 给每个子元素注解补充namespace属性
        @XmlElement(name = "Trip", namespace = "http://hacon.de/hafas/proxy/hafas-proxy")
        protected List<TripType> trip;
        @XmlElement(name = "Pricing", namespace = "http://hacon.de/hafas/proxy/hafas-proxy")
        protected List<PricingType> pricing;
        @XmlElement(name = "SotContext", namespace = "http://hacon.de/hafas/proxy/hafas-proxy")
        protected SotContextType sotContext;
        // 其余属性保持不变
        ...
    }
    

    TripType类的@XmlElement也需要补充相同的namespace属性。

    方案2:包级别统一配置命名空间,省去逐个添加的麻烦。在POJO所在包下创建package-info.java文件,内容如下:

    @XmlSchema(
        namespace = "http://hacon.de/hafas/proxy/hafas-proxy",
        elementFormDefault = XmlNsForm.QUALIFIED
    )
    package 你的POJO类所在包名;
    
    import javax.xml.bind.annotation.XmlNsForm;
    import javax.xml.bind.annotation.XmlSchema;
    

    配置后该包下所有JAXB注解的元素会默认继承该命名空间,不需要逐个添加namespace属性。

内容的提问来源于stack exchange,提问作者Chuck Nuris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:09:03