记一次 SpringBoot2.x 配置 Fastjson 的坑

踩坑记录

SpringBoot 默认自带jackson做为json的解析框架,但是呢有些个性化的需求配置和实现起来还是有的不太顺手,所以做为一直以来都是坚持使用的 fastjson 的人说,就得切换框架了。嗯,看起来是很简单的一个事情,Google 给了我19万6千条结果,百度不愧是“最牛逼”的,直接就是5百7十万,请看截图


5.png

image.png

看到这个结果,瞬间是神清气爽,抄起项目就是开干,导入依赖,注入配置,启动项目,那是一个一气呵成

20190529202551-3.png

激动的盯着 Spring Boot 这个风骚的启动页面,静静的等待结果出现....结果...不可描述,可以自行补脑。

在说填坑过程之前,我先把这几百万给的解决方案贴出来给大伙看看(其实也就把搜索出来的第一页结果看了一下,至于后面的文章里面有没有正确的我不敢保证了),几乎所有的文章的内容都是一样的内容。

第一步:导入依赖


    com.alibaba
    fastjson
    1.2.51

第二步:配置

方法一: 注入 bean 的方式

@SpringBootApplication
public class Application{
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        //1、定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //2、添加fastjson的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //3、在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //4、将convert添加到converters中
        HttpMessageConverter converter = fastConverter;
        return new HttpMessageConverters(converter);
    }
}

方法二:重写configureMessageConverters()方法

@SpringBootApplication
public class Application implements WebMvcConfigurer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configureMessageConverters(List> converters) {
        //1、定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //2、添加fastjson的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //3、在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //4、将convert添加到converters中
        converters.add(fastConverter);
    }
}

最后。。。。启动服务查看测试结果

---------------------然并卵--------------------------

首先要说说,方法一: 注入 bean 的方式。此方式在 springboot1.x 中是否有效我不知道,毕竟我很少玩1.x版本,不过看到前辈们这几百万的文章,我相信应该是有用的。但是,在我最新测试的SpringBoot 2.1.5中这种方式是无效的。

在来说就是第二种方式重写configureMessageConverters()方法。这种方式,在 SpringBoot2.x中也有些变化,如下:

public class Application extends WebMvcConfigurationSupport {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configureMessageConverters(List> converters) {
        //1、定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //2、添加fastjson的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //3、在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //4、将convert添加到converters中
        converters.add(fastConverter);
    }
}

在2.x 中不再需要实现WebMvcConfigurer接口,而是继承WebMvcConfigurationSupport类,当然重写方法是一样的。

重点:
这第二种方法不能说他是无效,但是尼玛,这种搞法会把 SpringBoot 内置的其他的默认MessageConverters全部覆盖掉,也就是说如果你这样做了,那么Controller就只能输出响应头是 application/json 的结果。比如项目中不是全部都是返回 json,有的是返回图片、xml 等等内容。这时候,就会发现请求直接406,后台输出错误:

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

如果你不相信你可以再重写方法

    @Override
    protected void extendMessageConverters(List> converters) {
        for (HttpMessageConverter messageConverter : converters) {
            System.out.println(messageConverter);
        }
    }

当没有重写configureMessageConverters方法,启动项目,控制输出是这样的:

20190529205145-1.png

加入重写之后是这样的:

20190529205242-2.png

之前输出的8个,现在只剩下1个了,这真是操碎了心啊。当然,如果项目就真是只有json输出,那也就无所谓了,但,我们这种超级无敌项目怎么可能就只有一种输出了。

经过对WebMvcConfigurationSupport的研究和无数次的 debug 跟踪,终于搞清楚了这个代码运行的各中逻辑,最后发现问题要得到完美解决,就加一句代码就搞定。

代码还是那个代码,只需在configureMessageConverters最后增加一句super.addDefaultHttpMessageConverters(converters); 就"完美"解决。

public class Application extends WebMvcConfigurationSupport {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configureMessageConverters(List> converters) {
        //1、定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //2、添加fastjson的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //3、在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //4、将convert添加到converters中
        converters.add(fastConverter);
        //5、追加默认转换器
        super.addDefaultHttpMessageConverters(converters);
    }
}

最后你就会看到控制台输出:

20190529210534-4.png

总结

百度需谨慎,代码有风险。

百度很多时候,确实给我们学习和解决问题带来很多便利。但是,在如今这个信息泛滥的时代,写篇文章记录是多么简单的一件事情,又不需要对读者负责任。所以,做为读者的我们,需要要有自己的思想和学习方法,能够在这成百上千百万信息中筛选出其中精华进行吸收,并能对一些糟粕的信息进行改进和完善再分享,那就最好了

此文章记录时间:2019年05月29日,时代在进步,技术在发展,如果你在未来侥幸搜索到此文章,请抱着谨慎的眼光借鉴和学习。

你可能感兴趣的:(记一次 SpringBoot2.x 配置 Fastjson 的坑)