You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:13:20