使用RestTemplate调用REST API时如何正确反序列化JAXBElement对象
问题根因
- Jackson默认不支持
javax.xml.bind.JAXBElement类型的反序列化:该类没有无参构造方法,也没有内置的序列化/反序列化逻辑适配 - 你自定义的
ObjectMapper未被RestTemplate生效使用:Spring Boot 自动注入的RestTemplate默认使用内置的ObjectMapper实例,不会自动拾取你标注了@Primary的自定义Bean,因此Mixin配置不会生效
可行解决方案
按推荐优先级排序:
方案1(最推荐,从根源解决问题):修改XSD生成类配置,去掉JAXBElement包装
XSD生成Java类时默认会将可选字段包装为JAXBElement,可通过修改生成配置直接生成普通类型字段,完全避免序列化问题:
- 在JAXB生成绑定文件
bindings.xjb中添加全局配置:
<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"> <jaxb:globalBindings generateElementProperty="false"/> </jaxb:bindings>
- 重新生成Java类,生成后的
AlternateNumberEntry21字段会直接是String、RingPattern等原生类型,没有JAXBElement包装,无需额外适配即可正常序列化反序列化。
方案2:使用官方JAXB适配模块,适配JAXBElement序列化
如果不能修改XSD生成配置,直接使用Jackson官方提供的JAXB注解模块完成适配:
- 引入依赖(Maven示例):
<dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-jaxb-annotations</artifactId> </dependency>
- 注册JAXB模块到自定义ObjectMapper:
@Bean @Primary public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); // 注册官方JAXB模块,自动支持JAXBElement、QName等JAXB专属类型的序列化反序列化 objectMapper.registerModule(new JaxbAnnotationModule()); return objectMapper; }
- 将自定义ObjectMapper配置到RestTemplate,替换默认内置实例:
@Bean public RestTemplate restTemplate(ObjectMapper objectMapper) { RestTemplate restTemplate = new RestTemplate(); // 遍历替换所有Jackson消息转换器的ObjectMapper for (HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) { if (converter instanceof MappingJackson2HttpMessageConverter jsonConverter) { jsonConverter.setObjectMapper(objectMapper); } } return restTemplate; }
方案3:修复现有Mixin方案
如果要保留自己写的Mixin逻辑,需要额外做两处修改:
- 参考方案2的步骤3,将自定义ObjectMapper配置到RestTemplate中,确保配置生效
- 新增QName类型的反序列化适配:你的Mixin构造参数中包含
QName类型,Jackson默认也无法反序列化该类型,需要额外添加QName的Mixin配置或者引入jackson-datatype-jsr310等JDK类型适配模块
内容的提问来源于stack exchange,提问作者gmexo
相关产品推荐
相关产品推荐

