springboot http序列化和反序列化HttpMessageConverter Converter 的优先级顺序

HttpMessageConverter  优先级

    // 添加converter的第一种方式,代码很简单,也是推荐的方式
    // 这样做springboot会把我们自定义的converter放在顺序上的最高优先级(List的头部)
    // 即有多个converter都满足Accpet/ContentType/MediaType的规则时,优先使用我们这个
    @Bean
    public MyMessageConverter converter()
    {
        System.out.println ("添加converter的第一种方式");
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 创建配置类
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.DisableCircularReferenceDetect
        );

        //此处是全局处理方式
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        config.setCharset(Charset.forName("UTF-8"));
        fastConverter.setFastJsonConfig(config);

        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.ALL);
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        fastConverter.setSupportedMediaTypes(supportedMediaTypes);
        //支持text 转string
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        //数据与javax.xml.transform.Source的相互转换
        SourceHttpMessageConverter sourceHttpMessageConverter = new SourceHttpMessageConverter ();

        //使用Jackson的XmlMapper转换XML数据
        Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
        builder.indentOutput(true);
        MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter = new MappingJackson2XmlHttpMessageConverter(builder.build());

        HttpMessageConverters httpMessageConverters = new HttpMessageConverters(mappingJackson2XmlHttpMessageConverter, sourceHttpMessageConverter, fastConverter,stringHttpMessageConverter );

        return  httpMessageConverters;
// 添加converter的第二种方式
    // 通常在只有一个自定义WebMvcConfigurerAdapter时,会把这个方法里面添加的converter(s)依次放在最高优先级(List的头部)
    // 虽然第一种方式的代码先执行,但是bean的添加比这种方式晚,所以方式二的优先级 大于 方式一
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        System.out.println ("添加converter的第二种方式");
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        //保留空的字段
        config.setSerializerFeatures(
                SerializerFeature.WriteNullListAsEmpty,//List null -> ""
                SerializerFeature.WriteNullStringAsEmpty,//String null -> ""
                SerializerFeature.WriteNullNumberAsZero,//Number null -> 0
                SerializerFeature.WriteMapNullValue);
        // 按需配置,更多参考FastJson文档哈

        //此处是全局处理方式
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        config.setCharset(Charset.forName("UTF-8"));

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        //处理中文乱码问题
//        List<MediaType> fastMediaTypes = new ArrayList<>();
//        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
//        converter.setSupportedMediaTypes(fastMediaTypes);
        converter.setSupportedMediaTypes(Arrays.asList(MediaType.ALL, MediaType.APPLICATION_JSON_UTF8,MediaType.APPLICATION_XML));
        converters.add(converter);

        // initialize your MappingJackson2XmlHttpMessageConverter
//        MappingJackson2XmlHttpMessageConverter xmlMessageConverter = new MappingJackson2XmlHttpMessageConverter();
//        xmlMessageConverter.setSupportedMediaTypes ();
//
//        //Here we add our custom-configured HttpMessageConverters
//        converters.add(new CustomObjectConverter(xmlMessageConverter));
//        super.configureMessageConverters(converters);
    }
    // 添加converter的第三种方式
    // 同一个WebMvcConfigurerAdapter中的configureMessageConverters方法先于extendMessageConverters方法执行
    // 可以理解为是三种方式中最后执行的一种,不过这里可以通过add指定顺序来调整优先级,也可以使用remove/clear来删除converter,功能强大
    // 使用converters.add(xxx)会放在最低优先级(List的尾部)
    // 使用converters.add(0,xxx)会放在最高优先级(List的头部)
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        System.out.println ("添加converter的第三种方式");
        // converters.add(new JavaSerializationConverter());
    }

 其中第一种方式 的 HttpMessageConverters httpMessageConverters = new HttpMessageConverters(mappingJackson2XmlHttpMessageConverter, sourceHttpMessageConverter, fastConverter,stringHttpMessageConverter );

看源码

 

这个是核心代码  决定Converter 的优先级顺序

private List<HttpMessageConverter<?>> getCombinedConverters(Collection<HttpMessageConverter<?>> converters, List<HttpMessageConverter<?>> defaultConverters) {
        List<HttpMessageConverter<?>> combined = new ArrayList();
        List<HttpMessageConverter<?>> processing = new ArrayList(converters);
        Iterator var5 = defaultConverters.iterator();

        while(var5.hasNext()) {
            HttpMessageConverter<?> defaultConverter = (HttpMessageConverter)var5.next();
            Iterator iterator = processing.iterator();

            while(iterator.hasNext()) {
                HttpMessageConverter<?> candidate = (HttpMessageConverter)iterator.next();
                if (this.isReplacement(defaultConverter, candidate)) {
                    combined.add(candidate);
                    iterator.remove();
                }
            }

            combined.add(defaultConverter);
            if (defaultConverter instanceof AllEncompassingFormHttpMessageConverter) {
                this.configurePartConverters((AllEncompassingFormHttpMessageConverter)defaultConverter, converters);
            }
        }

        combined.addAll(0, processing);
        return combined;
    }

参考 

https://www.cnblogs.com/page12/p/8168107.html

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值