• SpringBoot(十六):SpringBoot2.1.1集成fastjson,并使用fastjson替代默认的MappingJackson


    springboot2.1.1默认采用的json converter是MappingJackson,通过调试springboot项目中代码可以确定这点。在springboot项目中定义WebMvcConfig.java

    @Configuration
    @Import({WebMvcAutoConfiguration.class})
    @ComponentScan(
            value = "com.dx.test.web",
            includeFilters = {
                    @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
            })
    public class WebMvcConfig implements WebMvcConfigurer {
        /**
         * 使用 fastjson 代替 jackson
         *
         * @param converters
         */
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            List<HttpMessageConverter<?>> myConverters = converters;
        }
    }

    断电设置在"List<HttpMessageConverter<?>> myConverters = converters;"这行代码处,然后调试进入该出断电,查看converters集合下元素:

     从上表调试截图,可以发现springboot2.1.1默认采用的json converter是MappingJackson。

    新建SpringBoot项目,并引入fastjson:

    pom.xml配置如下:

     <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.1.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <dependencies>
            <!-- springboot web组件依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.56</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
        </dependencies>

    SpringBoot入口类:

    package com.dx.test.app;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * Hello world!
     */
    @SpringBootApplication(scanBasePackages = {"com.dx.test"})
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }

    使用fastjson作为springboot2.x的json converter的两种实现方法:

    1. 实现WebMvcConfigurer接口的void configureMessageConverters(List<HttpMessageConverter<?>> converters)方法;
    2. 在WebMvcConfigurer接口实现类内定义bean(HttpMessageConverters)

    为什么要使用fastjson替换jackson呢?

    1)fastjson快;

    2)国产,支持国产。

    实现WebMvcConfigurer接口来使用fastjson:

    实现代码如下:

    /**
     * WebMvcConfigurerAdapter 这个类在SpringBoot2.0已过时,官方推荐直接实现 WebMvcConfigurer 这个接口
     */
    @Configuration
    @Import({WebMvcAutoConfiguration.class})
    @ComponentScan(
            value = "com.dx.test.web",
            includeFilters = {
                    @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
            })
    public class WebMvcConfig implements WebMvcConfigurer {
        /**
         * 使用 fastjson 代替 jackson
         *
         * @param converters
         */
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            /*
             先把JackSon的消息转换器删除.
             备注:(1)源码分析可知,返回json的过程为:
                     Controller调用结束后返回一个数据对象,for循环遍历conventers,找到支持application/json的HttpMessageConverter,然后将返回的数据序列化成json。
                     具体参考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
                 (2)由于是list结构,我们添加的fastjson在最后。因此必须要将jackson的转换器删除,不然会先匹配上jackson,导致没使用 fastjson
            */
            for (int i = converters.size() - 1; i >= 0; i--) {
                if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                    converters.remove(i);
                }
            }
    
            FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
            //自定义fastjson配置
            FastJsonConfig config = new FastJsonConfig();
            config.setSerializerFeatures(
                    SerializerFeature.WriteMapNullValue,        // 是否输出值为null的字段,默认为false,我们将它打开
                    SerializerFeature.WriteNullListAsEmpty,     // 将Collection类型字段的字段空值输出为[]
                    SerializerFeature.WriteNullStringAsEmpty,   // 将字符串类型字段的空值输出为空字符串
                    SerializerFeature.WriteNullNumberAsZero,    // 将数值类型字段的空值输出为0
                    SerializerFeature.WriteDateUseDateFormat,
                    SerializerFeature.DisableCircularReferenceDetect    // 禁用循环引用
            );
            fastJsonHttpMessageConverter.setFastJsonConfig(config);
    
            // 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
            // 但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json
            // 参考它的做法, fastjson也只添加application/json的MediaType
            List<MediaType> fastMediaTypes = new ArrayList<>();
            fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
            fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
            converters.add(fastJsonHttpMessageConverter);
        }
    }

    实现思路,先把jackson从converters中移除掉,然后加入fastjson converter。

    注意:

    1)在该fastjson converter注入时,设置了fastjson配置信息:FastJsonConfig.setSerializerFeatures(循环依赖,是否输出null的字段等),这些设置将会影响Restful Api输出信息。

    2)但是这个设置并不会影响系统JSON.toJSONString(List<Article>)的配置信息,如果需要控制序列化配置,需要这么使用:

    // 序列化为json
    String content = JSON.toJSONString(orderByItems, SerializerFeature.WriteMapNullValue);

    在WebMvcConfigurer接口实现类内定义bean(HttpMessageConverters)来使用fastjson:

    实现代码如下:

    /**
     * WebMvcConfigurerAdapter 这个类在SpringBoot2.0已过时,官方推荐直接实现 WebMvcConfigurer 这个接口
     */
    @Configuration
    @Import({WebMvcAutoConfiguration.class})
    @ComponentScan(
            value = "com.dx.test.web",
            includeFilters = {
                    @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
            })
    public class WebMvcConfig implements WebMvcConfigurer {
        /**
         * +支持fastjson的HttpMessageConverter
         *
         * @return HttpMessageConverters
         */
        @Bean
        public HttpMessageConverters fastJsonHttpMessageConverters() {
            AbstractHttpMessageConverter abstractHttpMessageConverter = null;
            //1.需要定义一个convert转换消息的对象;
            FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
    
            //2:添加fastJson的配置信息;
            FastJsonConfig fastJsonConfig = new FastJsonConfig();
            fastJsonConfig.setSerializerFeatures(
                    SerializerFeature.WriteMapNullValue,
                    SerializerFeature.WriteDateUseDateFormat,
                    SerializerFeature.DisableCircularReferenceDetect);
            fastJsonConfig.setCharset(Charset.forName("utf-8"));
    
            //3处理中文乱码问题
            List<MediaType> fastMediaTypes = new ArrayList<>();
            fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
    
            //4.在convert中添加配置信息.
            fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
            fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
    
            HttpMessageConverter<?> converter = fastJsonHttpMessageConverter;
    
            return new HttpMessageConverters(converter);
        }
    }

    该方式会自动覆盖(替换jackson converter)。

    针对json输出字段处理:格式化日期&控制字段是否输出:

    1)日期格式化输出设置:只需要在实体的属性上添加注解@JSONField(format = "yyyy-MM-dd")

    public class MyVo {
        
        ...
    
        @JSONField(format = "yyyy-MM-dd")
        @ApiModelProperty(value = "最新StartTime,不存在时,返回null")
        private Date lastStartTimePlus1Day;// 最新startTime
    
        /**
         * @return the lastStartTimePlus1Day
         */
        public Date getLastStartTimePlus1Day() {
            return lastStartTimePlus1Day;
        }
    
        /**
         * @param lastStartTimePlus1Day the lastStartTimePlus1Day to set
         */
        public void setLastStartTimePlus1Day(Date lastStartTimePlus1Day) {
            this.lastStartTimePlus1Day = lastStartTimePlus1Day;
        }
    }

    2)控制字段是否输出,添加注解

    public class MyVo{
            ...
        @JSONField(serialize = true)
        @ApiModelProperty("权重排序:仅排序使用,序列化不输出")
        private Double weight;
        /**
         * @return the weight
         */
        public Double getWeight() {
            return weight;
        }
    
        /**
         * @param weight the weight to set
         */
        public void setWeight(Double weight) {
            this.weight = weight;
        }
    
    }
  • 相关阅读:
    设置maven阿里云镜像和公司私服并存
    idea favorites bookmarks标签收藏夹数据丢失bug
    C#后期绑定调用COM组件
    SQL Studio 1.0:一款轻便的SQL脚本工具兼容SQL Server、MySQL、Access2007
    SQL Studio 2.0: 新版发布
    SQLHelper用的不爽,试试CmdRunner吧
    Flask + uWSGI+ Linux 指南及避坑
    Flask + Pyinstaller 打包后运行报错 SystemError
    Url重写之UrlRewriter
    .net5 提取压缩包内指定文件内容无需解压
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11718641.html
Copyright © 2020-2023  润新知