zoukankan      html  css  js  c++  java
  • springboot升级2.0 fastjson报错? 2.0以上应该怎么整合fastjson?

    SpringBoot2.0如何集成fastjson?在网上查了一堆资料,但是各文章的说法不一,有些还是错的,可能只是简单测试一下就认为ok了,最后有没生效都不知道。恰逢公司项目需要将JackSon换成fastjson,因此自己来实践一下SpringBoot2.0和fastjson的整合,同时记录下来方便自己后续查阅。

    一、Maven依赖说明

      SpringBoot的版本为: <version>2.1.4.RELEASE</version>
      在pom文件中添加fastjson的依赖:
    <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
             <version>1.2.60/version>
    </dependency>
     

    二、整合

      整合之前,我们先说下springboot1.0的方法,轻车熟路的去自定了一个SpringMvcConfigure去继承WebMvcConfigurerAdapter,然后你就发现这个WebMvcConfigurerAdapter竟然过时了?what?点进去看源码:

     1 /**
     2  * An implementation of {@link WebMvcConfigurer} with empty methods allowing
     3  * subclasses to override only the methods they're interested in.
     4  *
     5  * @author Rossen Stoyanchev
     6  * @since 3.1
     7  * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made
     8  * possible by a Java 8 baseline) and can be implemented directly without the
     9  * need for this adapter
    10  */
    11 @Deprecated
    12 public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {}
     
      可以看到从spring5.0开始就被@Deprecated,原来是java8中支持接口中有默认方法,所以我们现在可以直接实现WebMvcConfigurer,然后选择性的去重写某个方法,而不用实现它的所有方法.
     
      于是就实现了WebMvcConfigurer:
     
     1 @Configuration
     2 public class SpringMvcConfigure implements WebMvcConfigurer {
     3  
     4     /**
     5      * 配置消息转换器
     6      * @param converters
     7      */
     8     @Override
     9     public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    10         FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
    11         //自定义配置...
    12         FastJsonConfig config = new FastJsonConfig();
    13         config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
    14                 SerializerFeature.WriteEnumUsingToString,
    15                 /*SerializerFeature.WriteMapNullValue,*/
    16                 SerializerFeature.WriteDateUseDateFormat,
    17                 SerializerFeature.DisableCircularReferenceDetect);
    18         fastJsonHttpMessageConverter.setFastJsonConfig(config);
    19         converters.add(fastJsonHttpMessageConverter);
    20     }
    21  
    22 }
     
      本以为这样子配置就可以完事儿,但是诡异的事情发生了,我明明注释了SerializerFeature.WriteMapNullValue,可是返回的json中仍然有为null的字段,然后我就去com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter中的writewriteInternal打了断点,再次执行,竟然什么都没有发生,根本没有走这两个方法,于是在自定义的SpringMvcConfigureconfigureMessageConverters方法内打了断点,想看看这个方法参数converters里边到底有什么:
     
      看到这里就想到,肯定是我自己添加的fastjson在后边,所以没有生效,所以就加了以下代码:
     
     1 @Override
     2 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     3     converters = converters.stream()
     4                 .filter((converter)-> !(converter instanceof MappingJackson2HttpMessageConverter))
     5                 .collect(Collectors.toList());
     6     FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
     7     //自定义配置...
     8     FastJsonConfig config = new FastJsonConfig();
     9     config.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
    10             SerializerFeature.WriteEnumUsingToString,
    11             /*SerializerFeature.WriteMapNullValue,*/
    12             SerializerFeature.WriteDateUseDateFormat,
    13             SerializerFeature.DisableCircularReferenceDetect);
    14     fastJsonHttpMessageConverter.setFastJsonConfig(config);
    15     converters.add(fastJsonHttpMessageConverter);
    16 }
     
      这还是不生效的,继续追踪,得出如下结论:
         (1)源码分析可知,返回json的过程为:
    Controller调用结束后返回一个数据对象,for循环遍历conventers,找到支持application/json的HttpMessageConverter,然后将返回的数据序列化成json。
    具体参考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
    (2)由于是list结构,我们添加的fastjson在最后。因此必须要将jackson的转换器删除,不然会先匹配上jackson,导致没使用fastjson
      最终得出代码如下:
     
     1 @Configuration
     2 public class SpringWebMvcConfigurer implements WebMvcConfigurer {
     3 
     4     private final Logger logger = LoggerFactory.getLogger(SpringWebMvcConfigurer.class);
     5 
     6     //使用阿里 FastJson 作为JSON MessageConverter
     7     @Override
     8     public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     9 
    10          /*
    11          先把JackSon的消息转换器删除.
    12          备注: (1)源码分析可知,返回json的过程为:
    13                     Controller调用结束后返回一个数据对象,for循环遍历conventers,找到支持application/json的HttpMessageConverter,然后将返回的数据序列化成json。
    14                     具体参考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
    15                (2)由于是list结构,我们添加的fastjson在最后。因此必须要将jackson的转换器删除,不然会先匹配上jackson,导致没使用fastjson
    16         */
    17         for (int i = converters.size() - 1; i >= 0; i--) {
    18             if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
    19                 converters.remove(i);
    20             }
    21         }
    22 
    23         FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
    24         FastJsonConfig config = new FastJsonConfig();
    25         config.setSerializerFeatures(
    26                 SerializerFeature.WriteMapNullValue,//保留空的字段
    27                 SerializerFeature.WriteNullStringAsEmpty,//String null -> ""
    28                 SerializerFeature.WriteNullNumberAsZero,//Number null -> 0
    29                 SerializerFeature.WriteDateUseDateFormat);//日期格式化
    30 
    31         converter.setFastJsonConfig(config);
    32         converter.setDefaultCharset(Charset.forName("UTF-8"));
    33         converters.add(converter);
    34     }
    35 }

     

      总结

    1. 最重要的还是解决了springboot2.0.2配置fastjson不生效的问题
    2. 更加明白stream api返回的都是全新的对象
    3. 更理解java是值传递而不是引用传递
    4. 了解到想要在迭代过程中对集合进行操作要用Iterator,而不是直接简单的for循环或者增强for循环
  • 相关阅读:
    C#多线程编程实战1.5检测线程状态
    C#多线程编程实战1.4终止线程
    C#多线程编程实战1.3等待线程
    C#多线程编程实战1.2暂停线程(休眠)
    C#多线程编程实战1.1创建线程
    C#中base的作用
    C#继承
    C#中return的两个作用
    Windows下完全卸载node.js并安装node.js的多版本管理工具nvm-windows
    执行gulp build报错
  • 原文地址:https://www.cnblogs.com/xujingyang/p/11679317.html
Copyright © 2011-2022 走看看