Spring Web:如何针对特定类禁用Jackson转换器
解决方案
核心思路
让Jackson的MappingJackson2HttpMessageConverter明确拒绝处理MyJsonClass类型,同时保留其对其他类型的转换能力;再确保自定义的MyJsonClassHttpMessageConverter能优先处理目标类型,从根源消除报错日志。
1. 处理WebMvc层面(服务端请求/响应转换)
修改WebMvcConfigurer的extendMessageConverters方法,先修改Jackson转换器的处理逻辑排除MyJsonClass,再将自定义转换器置于列表最前方:
@SpringBootApplication public class MyApplication implements WebMvcConfigurer { ... @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // 遍历修改所有Jackson转换器,让它们拒绝处理MyJsonClass for (HttpMessageConverter<?> converter : converters) { if (converter instanceof MappingJackson2HttpMessageConverter jacksonConverter) { MappingJackson2HttpMessageConverter filteredConverter = new MappingJackson2HttpMessageConverter(jacksonConverter.getObjectMapper()) { @Override public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) { Class<?> rawClass = getRawType(type); if (MyJsonClass.class.isAssignableFrom(rawClass)) { return false; } return super.canRead(type, contextClass, mediaType); } @Override public boolean canWrite(Class<?> clazz, MediaType mediaType) { if (MyJsonClass.class.isAssignableFrom(clazz)) { return false; } return super.canWrite(clazz, mediaType); } private Class<?> getRawType(Type type) { if (type instanceof Class<?>) { return (Class<?>) type; } else if (type instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) type).getRawType(); } // 按需扩展处理其他泛型类型(如数组、通配符类型) return Object.class; } }; // 替换原Jackson转换器 int index = converters.indexOf(converter); converters.set(index, filteredConverter); } } // 将自定义转换器添加到列表最前方,确保优先被调用 converters.add(0, new MyJsonClassHttpMessageConverter()); WebMvcConfigurer.super.extendMessageConverters(converters); } ... }
2. 处理RestTemplate层面(客户端请求/响应转换)
修改RestTemplateBuilder的配置逻辑,同样过滤Jackson转换器并添加自定义转换器:
@Bean RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer restTemplateBuilderConfigurer) { return restTemplateBuilderConfigurer.configure(new RestTemplateBuilder()) .messageConverters(converters -> { // 修改Jackson转换器,排除MyJsonClass for (Iterator<HttpMessageConverter<?>> iterator = converters.iterator(); iterator.hasNext(); ) { HttpMessageConverter<?> converter = iterator.next(); if (converter instanceof MappingJackson2HttpMessageConverter jacksonConverter) { MappingJackson2HttpMessageConverter filteredConverter = new MappingJackson2HttpMessageConverter(jacksonConverter.getObjectMapper()) { @Override public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) { Class<?> rawClass = getRawType(type); if (MyJsonClass.class.isAssignableFrom(rawClass)) { return false; } return super.canRead(type, contextClass, mediaType); } @Override public boolean canWrite(Class<?> clazz, MediaType mediaType) { if (MyJsonClass.class.isAssignableFrom(clazz)) { return false; } return super.canWrite(clazz, mediaType); } private Class<?> getRawType(Type type) { if (type instanceof Class<?>) { return (Class<?>) type; } else if (type instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) type).getRawType(); } return Object.class; } }; // 移除原转换器,添加过滤后的版本 iterator.remove(); converters.add(filteredConverter); } } // 添加自定义转换器到最前方 converters.add(0, new MyJsonClassHttpMessageConverter()); }); }
关键说明
- 过滤Jackson转换器:通过重写
canRead和canWrite方法,让Jackson明确跳过MyJsonClass的处理,避免尝试转换时产生错误日志。 - 自定义转换器优先级:将自定义转换器放在列表首位,确保Spring处理
MyJsonClass时优先使用你的实现。 - 保留原有配置:过滤后的Jackson转换器复用了原有
ObjectMapper的配置,不会影响其他类型的正常转换。
内容的提问来源于stack exchange,提问作者nonzaprej
相关产品推荐
相关产品推荐

