SpringBoot读取properties中文乱码解决方案
目录
一、问题描述
二、解决方案
2.1、网络上的解决办法
2.1.1、修改IDEA编码?
2.1.2、改为yml配置
2.1.3、读取时设置编码
2.2、重写资源加载类(个人推荐)
一、问题描述
由于业务需求需要在application.properties中配置一个带有中文字符串的参数,注入到业务类中,但是发现注入的中文是乱码的。大概情况如下所示:
package com.cnstar.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* cnstar单元测试
* @author cnstar
**/
@SpringBootTest(classes = TestApplication.class)
@RunWith(SpringRunner.class)
public class CnstarTest {
@Value("${name}")
private String name;
@Test
public void test1() {
System.out.println("中文内容:" + name);
}
}
打印输出结果:
二、解决方案
2.1、网络上的解决办法
遇到问题首先想到网络上找解决方案,网络上的解决办法基本一致,概括为以下三种。
2.1.1、修改IDEA编码
在IDEA中将所有的编码设置为UTF-8,同时勾上Transparent native-to-ascii conversion的选项,然后重新创建application.properties的文件。
运行结果:
但是这个配置文件用记事本打开编辑时,发现内容被修改成了unicode编码,在线上修改时变得很困难,所以此方式我不做推荐。
2.1.2、改为yml配置
就是将application.properties的文件修改为application.yml的结构,重启项目。
运行效果
证明是可行的。这种方式可以根据自己需求选择,但是当配置文件的内容层级较深时也不推荐,容易看错行配置。
2.1.3、读取时设置编码
package com.cnstar.test.property;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.annotation.PostConstruct;
@Configuration
@PropertySource(value = "classpath:application.properties", encoding = "utf-8")
public class CnstarProperty {
@Value("${name}")
private String name;
@PostConstruct
public void init() {
System.out.println("name is :" + name);
}
}
亲测发现这种方式针对application.properties是不行的。
但是针对其他名称的properties文件是可以的
package com.cnstar.test.property;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.annotation.PostConstruct;
@Configuration
@PropertySource(value = "classpath:test.properties", encoding = "utf-8")
public class CnstarProperty {
@Value("${name2}")
private String name;
@PostConstruct
public void init() {
System.out.println("name is :" + name);
}
}
运行结果:
2.2、重写资源加载类(个人推荐)
1、创建一个类继承PropertiesPropertySourceLoader,因SpringBoot版本不同PropertiesPropertySourceLoader****类会有差别,本文采用的SpringBoot版本是2.3.12.RELEASE。
package com.cnstar.utils;
import org.springframework.core.io.*;
import org.springframework.core.env.*;
import org.springframework.boot.env.*;
import java.util.*;
import java.io.*;
/**
* 解快springBoot读取properties配置文件中文乱码的问题
* @author cnstar
**/
public class SelfPropertySourceLoader extends PropertiesPropertySourceLoader {
@Override
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
Map<String, ?> properties = this.loadUseUtf8(resource);
if (properties.isEmpty()) {
return Collections.emptyList();
}
return Collections.singletonList(new OriginTrackedMapPropertySource(name, Collections.unmodifiableMap((Map<?, ?>)properties), true));
}
private Map<String, ?> loadUseUtf8(Resource resource) throws IOException {
Properties props = new Properties();
InputStream is = resource.getInputStream();
try {
String filename = resource.getFilename();
if (filename != null && filename.endsWith(".xml")) {
props.loadFromXML(is);
}
else {
props.load(new InputStreamReader(is, "utf-8"));
}
} finally {
is.close();
}
return (Map)props;
}
}
2.在resource目录下创建目录META-INF,在META-INF目录下创建文件spring.factories
内容如下:
org.springframework.boot.env.PropertySourceLoader=com.cnstar.utils.SelfPropertySourceLoader
重新运行: