Jackson XML无法正确反序列化Jakarta的XmlElements字段
问题:Jackson XML反序列化时@XmlElements注解字段返回null
使用Jackson XML进行Jakarta反序列化时,带有@XmlElements注解的字段始终返回null,但仅用@XmlElement的普通字段能正常解析。相关代码如下:
Java实体类代码
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "posinfo" }) @XmlRootElement(name = "PUSH") public class PUSH { @XmlElement(name = "posinfo") protected List<PosinfoType> posinfo; // 省略getter/setter等方法 } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "posinfoType", propOrder = { "delayAndINITAndARRIVAL", "delimiterAndAny" }) public class PosinfoType { @XmlElements({ @XmlElement(name = "DELAY", type = DELAYType.class), @XmlElement(name = "INIT", type = INITType.class), @XmlElement(name = "ARRIVAL", type = ARRIVALType.class), @XmlElement(name = "ONSTOP", type = ONSTOPType.class), @XmlElement(name = "DEPARTURE", type = DEPARTUREType.class), @XmlElement(name = "ONROUTE", type = ONROUTEType.class), @XmlElement(name = "ONPATH", type = ONPATHType.class), @XmlElement(name = "OFFROUTE", type = OFFROUTEType.class), @XmlElement(name = "END", type = ENDType.class) }) protected List<Object> delayAndINITAndARRIVAL; @XmlElementRef(name = "delimiter", namespace = "http://example.com/tmi8/core", type = Delimiter.class, required = false) @XmlAnyElement(lax = true) protected List<Object> delimiterAndAny; // 省略getter/setter等方法 }
待解析的XML片段
<posinfo> <ONROUTE> <timestamp>2024-05-14T16:18:14+00:00</timestamp> <source>VEHICLE</source> </ONROUTE> <ONSTOP> <timestamp>2024-05-14T16:18:14+00:00</timestamp> <source>VEHICLE</source> </ONSTOP> <ARRIVAL> <timestamp>2024-05-14T16:18:16+00:00</timestamp> <source>VEHICLE</source> </ARRIVAL> </posinfo>
Jackson配置代码(Kotlin)
object JacksonJaxbUtils { val objectMapperXml: ObjectMapper = XmlMapper.builder().apply { defaultUseWrapper(false) enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION) addModule(JakartaXmlBindAnnotationModule()) disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) serializationInclusion(JsonInclude.Include.NON_EMPTY) addModule( JavaTimeModule().apply { addSerializer(XMLGregorianCalendar::class.java, XMLGregorianCalendarSerializer()) } ) }.build() class XMLGregorianCalendarSerializer : JsonSerializer<XMLGregorianCalendar>() { override fun serialize(value: XMLGregorianCalendar, generator: JsonGenerator, provider: SerializerProvider) { generator.writeString(value.toXMLFormat()) } } }
解决方案
- 版本兼容性检查:确保
jackson-module-jakarta-xmlbind-annotations与jackson-dataformat-xml版本完全一致,版本不匹配会导致JAXB注解无法被正确识别。 - 显式初始化列表:Jackson不会自动初始化空列表,需在
PosinfoType中为字段赋值:@XmlElements({ // 注解内容不变 }) protected List<Object> delayAndINITAndARRIVAL = new ArrayList<>(); - 调整包装器配置:全局
defaultUseWrapper(false)会干扰@XmlElements字段的解析逻辑,可直接移除该配置;若必须保留,需给目标字段添加注解明确禁用包装:@XmlElements({ // 注解内容不变 }) @JacksonXmlElementWrapper(useWrapping = false) protected List<Object> delayAndINITAndARRIVAL = new ArrayList<>(); - 验证子类型注解:确认
DELAYType、ONROUTEType等子类都正确添加了JAXB注解(如@XmlType或@XmlRootElement),否则Jackson无法完成XML元素到Java类的映射。
内容的提问来源于stack exchange,提问作者MrAndre
相关产品推荐
相关产品推荐

