Spring中为@RequestBody编写自定义HttpMessageConverter时的Jackson反序列化异常问题求助
解决Spring自定义HttpMessageConverter在application/json下不生效的问题
这个问题的核心原因很明确:Spring默认的MappingJackson2HttpMessageConverter会优先处理application/json类型的请求,而且它也尝试将JSON反序列化为MyType(虽然最终失败了),所以你的自定义转换器根本没机会执行,才会抛出Jackson无法实例化MyType的异常。而当你用text/plain时,Jackson转换器不处理这个媒体类型,所以你的自定义转换器才会被正常触发。
下面是几种可行的解决方案:
方案1:提高自定义转换器的优先级
在Spring的消息转换器列表中,优先级靠前的转换器会先被匹配。你可以在配置类中把自定义转换器放在列表的最前面:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 将自定义转换器添加到列表首位,确保优先匹配 converters.add(0, new MyConverter()); // 如果还需要Jackson处理其他JSON类型的请求,手动添加回去(可选) converters.add(new MappingJackson2HttpMessageConverter()); } }
另外,你也可以给自定义转换器添加@Order注解,直接设置最高优先级:
@Order(Ordered.HIGHEST_PRECEDENCE) public class MyConverter extends AbstractHttpMessageConverter<MyType> { // ... 你的原有代码 }
方案2:移除默认的Jackson转换器(谨慎使用)
如果你的应用不需要Jackson处理任何JSON请求,可以直接清空默认转换器列表,只保留自定义的:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.clear(); // 清空所有默认转换器 converters.add(new MyConverter()); } }
注意:这个方法会影响所有JSON类型的请求处理,如果你还有其他需要Jackson反序列化的DTO,不建议使用该方案。
补充:完善自定义转换器的读取逻辑
确保你的readInternal方法正确读取请求体内容,推荐用Spring的StreamUtils工具类简化代码:
@Override protected MyType readInternal(Class<? extends MyType> type, HttpInputMessage inputMessage) throws IOException { // 读取请求体为UTF-8编码的字符串 String jsonContent = StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8); return MyType.build(jsonContent); }
验证
重启应用后,发送Content-Type: application/json的POST请求,此时Spring会优先使用你的自定义转换器,通过MyType.build()方法实例化对象,不再触发Jackson的反序列化异常。
内容的提问来源于stack exchange,提问作者Stormcloud
相关产品推荐
相关产品推荐

