欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记录一次fastjson调用的奇怪问题

程序员文章站 2022-06-17 09:22:09
...

一、项目背景

        研究什么时候会调用fastjson,什么时候调用默认的jackson

二、使用对比

    1.Spring项目开启fastjson支持

        

    <!-- 启动spring mvc的注解功能 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!-- 配置Fastjson支持 -->
            <bean
                class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json</value>
                    </list>
                </property>
<!--                <property name="features">
                    <list>
                        <value>WriteMapNullValue</value>
                        <value>QuoteFieldNames</value>
                    </list>
                </property>-->
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

此时如果在代码里手动调用JSON.toJSONString(map, SerializerFeature.WriteMapNullValue)(map是一个hashmap的实例)并且Controller层的方法家还是那个@Responsebody注解。将会出现手动调用fastjson然后调用fastjson的writeInternal(Object obj, HttpOutputMessage outputMessage)方法

但是此时去掉<value>application/json</value>这一项会出现不会手动调用writeInternal方法,此时接口的实现类调用的是StringHttpMessageConverter,实现方法是writeInternal(String s, HttpOutputMessage outputMessage)。

三、结果原因分析 :

    1.一开始我以为是更细化的实现类优先调用,即先调用默认的String类型。

        找不到再调用fastjson的writeInternal方法。然而类型确定会这样,但是此时最主要的区别是请求头的区别,请看

    

Content-Type: application/json;charset=UTF-8
X-Requested-With: XMLHttpRequest
Accept: application/json

此时接收的请求正好符合我们预定义好的属性。也就是说不是类型问题。

2.那么是Accept类型导致了fastjson两次序列化的问题。

请求头去掉accept属性后,List<MediaType> producibleMediaTypes = this.getProducibleMediaTypes(servletRequest, returnValueClass); 的属性接受变为*/*。

List<MediaType> producibleMediaTypes = this.getProducibleMediaTypes(servletRequest, returnValueClass);的值 

加一个*/*,其他如application/json等等。

此时还会调用fastjson方法。

   3.去掉<value>application/json</value>支持

        此时调用的是默认的StringHttpMessageConverter。很奇怪,进入源码分析。此时请求头依旧为Accept: application/json,返回的是一次手动序列化的结果,没有调用fastjson。那么意味着只要fastjson没有配置application/json支持,并且accept配置为Accept: application/json将不会调用fastjson。记录一次fastjson调用的奇怪问题

也就是说,如果fastjson这边配置了supportedMediaTypes,如果请求头的accept不在这个支持范围内,调用的是默认的转换器。


相关标签: fastjson