SpringBoot配置文件中文乱码问题的简便解决方案
在开发过程中我经常遇到需要在配置文件中设置中文的场景,如果让Sring或SpringBoot直接读取这些配置项的值,就会遇到中文乱码的问题。原因是Spring和SpringBoot都是通过JDK的Properties
类载入*.properties
类型的配置文件的,而Properties
类会默认以ISO-8859-1
的编码方式对配置文件进行解码,该编码方式不支持中文字符从而导致乱码出现。
一些可行的方案
JDK官方文档对该问题建议的解决方案是:将无法使用ISO-8859-1
字符集表示的字符使用UniCode逃逸符进行转换。举个例子说明,假如我有以下的中文配置项,直接使用如下的配置会导致中文读取乱码,不管你的配置文件编码是什么:
my-project.config-in-chinese=我是中文配置项
如果想让最终读取到Context
中的配置项值为我是中文配置项
,那么可以将该配置项改为:
my-project.config-in-chinese=\u6211\u662f\u4e2d\u6587\u914d\u7f6e\u9879
其中\u6211\u662f\u4e2d\u6587\u914d\u7f6e\u9879
即为我是中文配置项
的Unicode
编码值,可以在使用具站长工具等在线转换工具得到任意中文字符串的Unicode编码值。
上述方法虽然能够解决问题,但是如果需要修改配置项,那么还要先进行配置项的字符编码转换,这给线上运营部署带来了不少的麻烦。另外的一种解决方案是使用xml
或yaml
格式的配置文件代替properties
配置文件,但是这仅对使用了SpringBoot的项目较为方便,而我们还是会有很多仅使用了Spring框架的老代码。并且,更换配置文件类型也需要付出一定的学习代价。
或许简便的方案
回顾一下本文开始对配置文件中文乱码的原因解释,可以发现乱码是由于Spring/SpringBoot只能用Properties
类解析properties
类型的配置文件,而Properties
又默认使用ISO-8859-1
字符编码。因此我们可以对Properties
类解析后配置先按照ISO-8859-1
字符集进行编码得到原始的bytes
数组(实际就是配置文件在磁盘上的原始值),然后再按照配置文件的字符编码(假设是UTF-8
)字符集进行解码就可以得到正确的配置项的Unicode值。为了实现上述流程,我们需要在通过@Value
注解注入配置项的时候(或者使用配置项之前)对代码做如下修改:
@Component
public class ConfigureEncodingTest {
private String configure;
@Autowired
public void setConfigure(@Value("${my-project.config-in-chinese}") String configure) {
// 对从配置文件中读出来的值先按ISO-8859-1进行编码,得到原始的byte数组,然后重新按照UTF-8进行解码
this.configure = new String(configure.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
}
public String getConfigure() {
return configure;
}
/* ... Your Service... */
}
这种方法可以不必对配置文件做任何修改,可以方便运维在线上随时修改配置项,但是毕竟这样对代码进行修改会有些别扭,大家可以根据自己的喜好和业务场景自行选择合适的方案。