Springboot2配置FastJsonHttpMessageConverter不生效,FastJsonHttpMessageConverter返回类型字符串String中文乱码问题

最近项目遇到的这两个问题,看了很多文章,总结一下经验,非常实用,亲测有效,希望能帮助到大家。

FastJsonHttpMessageConverter不生效问题:

在原来springboot1.X 版本中是可以生效,配置代码:

    /**
     * 替换使用 FastJson 解析返回结果
     */
    @Override  
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {  
        //1.先定义一个convert转换消息的对象
        FastJsonJsonpHttpMessageConverter fastConverter = new FastJsonJsonpHttpMessageConverter();
        //2.添加fastjson的配置信息,比如:是否要格式化返回的json数据
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        
        //处理中文乱码问题(不然出现中文乱码)
        List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        
        //3.在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //4.将convert添加到converters当中
        converters.add(fastConverter);
    } 
    @JSONField(name = "Code")
    private String code;

升级为springboot2后,响应 FastJsonHttpMessageConverter 未起作用,@JSONField(name = "Code")注释后的code返回还是小写。

"data": [
		{
			"code": "IronCell",
			"description": "锂离子电池"
		},
		{
			"code": "MetalCell",
			"description": "锂金属电池"
		}
	]

按照对springmvc的了解 ,如果自定义不生效的话,应该是使用默认消息转换器。为验证想法,在配置中添加如下代码打印出消息转换器列表:

public class SysWebMvcConfigurer implements WebMvcConfigurer {


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

输出如下信息:

org.springframework.http.converter.ByteArrayHttpMessageConverter@433e3357
org.springframework.http.converter.StringHttpMessageConverter@4a1066a2
org.springframework.http.converter.StringHttpMessageConverter@37531849
org.springframework.http.converter.ResourceHttpMessageConverter@1cc4de0
org.springframework.http.converter.ResourceRegionHttpMessageConverter@54629d11
org.springframework.http.converter.xml.SourceHttpMessageConverter@66f4a841
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@49ca7586
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@61a93e7c
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@2a0a9212
com.dreamer.core.converter.FastJsonJsonpHttpMessageConverter@6a400857
 

可以看出自定义的消息转换器【FastJsonJsonpHttpMessageConverter】在列表最后。

根据消息转换器的应用规则,会顺序选择符合要求的消费转换器,MappingJackson2HttpMessageConverter 在 FastJsonJsonpHttpMessageConverter 前面,这样就会使用 MappingJackson2HttpMessageConverter  进行消费转换,为了确认想法正确,我在 MappingJackson2HttpMessageConverter  -> writeInternal 方法进行了debug,运行后,确实与想法一致。

找到原因,那就只要把 自定义的消息转换器【FastJsonJsonpHttpMessageConverter】添加到 MappingJackson2HttpMessageConverter 前面就可以,而对于自定义的消息转换器配置还有另一种方式,如下:

​
@Configuration
public class MessageConverConfig {
    
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        /**
         * 1.先定义一个convert转换消息的对象 
         * 2.添加fastjson的配置信息,比如:是否要格式化返回的json数据 
         * 3.在convert中添加配置信息 
         * 4.将convert添加到converters当中
         */
        // 1.先定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 2.添加fastjson的配置信息,比如:是否要格式化返回的json数据
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
            SerializerFeature.PrettyFormat,
            SerializerFeature.WriteNullListAsEmpty,
            SerializerFeature.WriteMapNullValue,
            SerializerFeature.WriteNullStringAsEmpty
        );

        // 处理中文乱码问题(不然出现中文乱码)
        List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);

        // 3.在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);

        return new HttpMessageConverters(fastConverter);
    }

}

​

配置后,重启项目,看到项目中消息转换器列表打印如下内容:

com.dreamer.core.converter.FastJsonJsonpHttpMessageConverter@75652058
org.springframework.http.converter.ByteArrayHttpMessageConverter@30fa29ef
org.springframework.http.converter.StringHttpMessageConverter@7749f8a4
org.springframework.http.converter.ResourceHttpMessageConverter@5351785e
org.springframework.http.converter.ResourceRegionHttpMessageConverter@f6af58c
org.springframework.http.converter.xml.SourceHttpMessageConverter@6ebe10df
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@560a4974
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@e415863
 

这里就可以看出 自定义的消息转换器【FastJsonJsonpHttpMessageConverter】在 MappingJackson2HttpMessageConverter 前面 ,同时运行API,debug 是运行 FastJsonJsonpHttpMessageConverter  -> writeInternal 方法 。消息也可以正常转换,配置成功!

"data": [
		{
			"Code": "IronCell",
			"Description": "锂离子电池"
		},
		{
			"Code": "MetalCell",
			"Description": "锂金属电池"
		}
	]

FastJsonHttpMessageConverter返回类型字符串String中文乱码问题

配置成FastJsonHttpMessageConverter后,controller返回String类型,浏览器访问却中文乱码:


@RestController
public class HomeController {

    @GetMapping(value = "/welcome")
    public String welcome() {
        return "欢迎来到XXX!";
    }
}

返回String数据到浏览器时中文乱码。查看Response返回编码: 

这里写图片描述

格式跟浏览器格式不匹配,需要UTF-8。 
查看StringHttpMessageConverter源码(截取部分):

public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
    public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
}

解决方法一 
在RequestMapping里设置 produces = { “application/json;charset=UTF-8” }: 

但是麻烦,每个controller都要写一次。

解决方法二 

在之前设置HttpMessageConverters的地方添加StringHttpMessageConverter配置:

@Configuration
public class MessageConverConfig {
    
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        /**
         * 1.先定义一个convert转换消息的对象 
         * 2.添加fastjson的配置信息,比如:是否要格式化返回的json数据 
         * 3.在convert中添加配置信息 
         * 4.将convert添加到converters当中
         */
        // 1.先定义一个convert转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 2.添加fastjson的配置信息,比如:是否要格式化返回的json数据
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
            SerializerFeature.PrettyFormat,
            SerializerFeature.WriteNullListAsEmpty,
            SerializerFeature.WriteMapNullValue,
            SerializerFeature.WriteNullStringAsEmpty
        );

        // 处理中文乱码问题(不然出现中文乱码)
        List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);

        // 3.在convert中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        
        // 修改StringHttpMessageConverter默认配置
        StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);

        return new HttpMessageConverters(fastConverter, converter);
    }

}

问题解决。

参考地址:

https://blog.csdn.net/x_iya/article/details/77872173

https://blog.csdn.net/Axela30W/article/details/80817243

https://blog.csdn.net/weixin_34029680/article/details/92021359

猜你喜欢

转载自blog.csdn.net/qq_26878363/article/details/97389275