Spring Boot 2.4升级至2.5后自定义Jackson Polygon反序列化器不生效如何解决
问题描述
太长不看版:我该如何让Spring使用我自定义的反序列化器?我已经排查过但仍然无法解决
我有一个标注@PostMapping的接口,@RequestBody参数为Polygon类型;它接收包含坐标点的嵌套数组,需要转换为org.elasticsearch.geometry.Polygon类型:
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<List<SearchDTO>> findSpatialResults(@RequestBody Polygon polygon) {...}
该功能需要自定义反序列化器,实现代码如下:
public class PolygonDeserializer extends StdDeserializer<Polygon> { public PolygonDeserializer() { super(Polygon.class); } @Override public Polygon deserialize(JsonParser jp, DeserializationContext context) throws IOException { ObjectCodec oc = jp.getCodec(); JsonNode node = oc.readTree(jp); ... } }
该反序列化器在标注了@Configuration的SpringConfig类中注册,注册代码如下:
@Configuration public class SpringConfig { @Bean public Module polygonDeserializer() { SimpleModule module = new SimpleModule(); module.addDeserializer(Polygon.class, new PolygonDeserializer()); return module; } }
Spring Boot版本升级前该功能运行正常,升级后报错:JSON parse error: Cannot deserialize instance of org.elasticsearch.geometry.Polygon out of START_ARRAY token,无法定位问题原因。
解决方案
- 首先确认
SpringConfig配置类是否在Spring Boot启动类的包扫描范围内,若不在可以在启动类上加@Import(SpringConfig.class)强制导入配置。 - 若项目中手动定义了
ObjectMapperBean,需要手动将自定义反序列化模块注册到该实例中,自动装配的Module不会对手动创建的ObjectMapper生效:
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); // 手动注册自定义反序列化模块 SimpleModule module = new SimpleModule(); module.addDeserializer(Polygon.class, new PolygonDeserializer()); mapper.registerModule(module); return mapper; }
- 排查项目是否引入了Gson、Fastjson等其他JSON序列化工具,若存在可以在配置文件中指定优先使用Jackson:
# Spring Boot 2.x 及以上版本配置 spring.mvc.converters.preferred-json-mapper=jackson
- 也可以直接通过Web MVC配置手动给消息转换器注册反序列化器,优先级高于全局ObjectMapper配置:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { for (HttpMessageConverter<?> converter : converters) { if (converter instanceof MappingJackson2HttpMessageConverter jsonConverter) { ObjectMapper mapper = jsonConverter.getObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(Polygon.class, new PolygonDeserializer()); mapper.registerModule(module); break; } } } }
- 若以上配置都不生效,可以在反序列化器的
deserialize方法首行加断点,确认请求是否进入该方法:- 未进入:说明反序列化器未被正确注册,可排查配置类的加载顺序、是否有其他配置覆盖了消息转换器
- 已进入仍报错:说明反序列化逻辑存在问题,需检查传入的JSON数组结构和解析逻辑是否匹配
内容的提问来源于stack exchange,提问作者nonNumericalFloat
相关产品推荐
相关产品推荐

