SpringBoot 解决乱码问题:通过 spring.http.encoding.charset 指定返回 UTF-8 编码

在使用 SpringBoot 开发后端系统时,为了能让返回的内容在不同浏览器(比如有些人使用英文版的 chrome)不同终端下都不会出现乱码问题,我们一般需要强制指定返回的编码类型为 UTF-8。

配置如下:

1
2
3
4
# application.properties
spring.http.encoding.force=true
spring.http.encoding.enabled=true
spring.http.encoding.charset=UTF-8

原理

这三个配置其实是在 CharacterEncodingFilter 类中起到作用的,CharacterEncodingFilter 类用过 SpringBoot 的同学应该很熟悉,是一个专门处理 HTTP 编码的 Filter。

在 SpringBoot 启动时,HttpEncodingAutoConfiguration 这个自动装配类会将编码相关的配置读取到 HttpEncodingProperties 对象中。并且会实例化 CharacterEncodingFilter 对象,并在实例化的过程中读取 HttpEncodingProperties 里的内容,作为设置返回编码的依据。

源码片段:

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
@Configuration
@EnableConfigurationProperties(HttpEncodingProperties.class)
@ConditionalOnWebApplication
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

private final HttpEncodingProperties properties;

public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}

@Bean
@ConditionalOnMissingBean(CharacterEncodingFilter.class)
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}

// ...
}