0%

Spring Boot 2.3.1.RELEASE 解决中文乱码的三种方法

近日项目将 Spring Boot 升级到了最新 2.3.1.RELEASE,发现接口返回内容的中文都是乱码

1
{"errorCode":0,"message":"操作成功"}

度娘了好久,发现大都是过时的方法,在 Spring Boot 2.3.1.RELEASE 中无效, 经过源码分析+实践,确定如下三种方法可以解决中文乱码,解决后结果如下:

1
{"errorCode":0,"data":null,"message":"操作成功"}

解决方法

方法一:设置全局的编码格式为UTF-8

application.yml中添加如下配置

1
2
3
4
5
6
server:
servlet:
encoding:
charset: utf-8
force: true
enabled: true

参考官方文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#server-properties

方法二:继承 WebMvcConfigurationSupport

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {

@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
// 解决 Controller 返回普通文本中文乱码问题
if (converter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
}

// 解决 Controller 返回json对象中文乱码问题
if (converter instanceof MappingJackson2HttpMessageConverter) {
((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
}
}
}
}

原理可以参考如下源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 这个方法为 RequestMappingHandlerAdapter 和 ExceptionHandlerExceptionResolver 提供了访问共享的 HttpMessageConverter 的能力
* RequestMappingHandlerAdapter 的职责就包括对于 @RequestMapping 注解的解析处理能力
* ExceptionHandlerExceptionResolver 的职责就包括对于 @ExceptionHandler 注解的解析处理能力
*/
protected final List<HttpMessageConverter<?>> getMessageConverters() {
if (this.messageConverters == null) {
this.messageConverters = new ArrayList<>();
/*
* 空方法,留给子类扩展
* 通过这个方法可以添加自己的针对特定内容类型的实例,则可以达到优先级最高,等同于屏蔽掉列表中其他同类型实例
*/
configureMessageConverters(this.messageConverters);
if (this.messageConverters.isEmpty()) {
// 添加默认的各种converter
addDefaultHttpMessageConverters(this.messageConverters);
}
/*
* 空方法,留给子类扩展
* 可以针对框架自带的默认的各种类型的 HttpMessageConverter 实例进行一些属性上的自定义设置
*/
extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}

方法三:设置 @RequestMapping 的 produces 属性

把 content-type 的 charset 设置为utf-8

1
@RequestMapping(value = "queryXXX", produces = "application/json;charset=UTF-8")

这种方法每个 Controller 都要加,比较麻烦,不推荐