当前位置:网站首页>成功解决之微服务@Value获取配置文件乱码问题
成功解决之微服务@Value获取配置文件乱码问题
2022-06-26 18:10:00 【JobsTribe】
问题描述
微服务中获取properties时:
mystyle.station.content = 测试中文字符
相关代码:
@Slf4j
@Component
public class GetPropertiesValueDemo {
@Value("${mystyle.station.content}")
private String content;
@PostConstruct
public String getCreateContent(){
try {
log.info(this.getClass().getSimpleName() +"_getCreateContent starts,content:{}",content);
String utf8Content = new String(content.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
log.info(this.getClass().getSimpleName() +"_getCreateContent starts,utf8Content:{}",utf8Content);
} catch (Exception e) {
log.error("e:{}",e);
}
return "success";
}
}
在用@Value获取值时出现乱码问题。
GetPropertiesValueDemo_getCreateContent starts,content:å°Šæ•¬çš„ç”¨æˆ·ï¼Œæ‚¨çš„æ‰‹æœºå·²æ¬ è´¹ï¼Œè¯·æ‚¨åŠæ—¶äº¤è´¹ã€‚详æƒ
请拨打<电è¯>。
原因分析
结论
通过源码分析和相关文章可以知道,application.properties默认是ISO-8859-1格式来加载的。
查看源码的路径如下:底层源码jar包为:
- org.springframework.boot:spring-boot:2.1.3.RELEASE
查看类的相关代码顺序:
ConfigFileApplicationListener loadDocuments -->PropertySourceLoader load --> PropertiesPropertySourceLoader loadProperties -->OriginTrackedPropertiesLoader load --> OriginTrackedPropertiesLoader CharacterReader
具体源码分析如下:
ConfigFileApplicationListener类
类所在地址为:org.springframework.boot.context.config。
此类作用:加载配置文件的属性,可以加载”application.properties“和”application.yml“的文件属性,也可以加载获取活动配置的文件。
private List<Document> loadDocuments(PropertySourceLoader loader, String name,
Resource resource) throws IOException {
DocumentsCacheKey cacheKey = new DocumentsCacheKey(loader, resource);
List<Document> documents = this.loadDocumentsCache.get(cacheKey);
if (documents == null) {
List<PropertySource<?>> loaded = loader.load(name, resource);
documents = asDocuments(loaded);
this.loadDocumentsCache.put(cacheKey, documents);
}
return documents;
}
PropertiesPropertySourceLoader类
此类作用:将”.properties“文件加载到PropertySource中。
区分调用是.xml文件结尾还是其他文件类型,然后调用不同的方法。
public class PropertiesPropertySourceLoader implements PropertySourceLoader {
private static final String XML_FILE_EXTENSION = ".xml";
@Override
public String[] getFileExtensions() {
return new String[] {
"properties", "xml" };
}
@Override
public List<PropertySource<?>> load(String name, Resource resource)
throws IOException {
Map<String, ?> properties = loadProperties(resource);
if (properties.isEmpty()) {
return Collections.emptyList();
}
return Collections
.singletonList(new OriginTrackedMapPropertySource(name, properties));
}
@SuppressWarnings({
"unchecked", "rawtypes" })
private Map<String, ?> loadProperties(Resource resource) throws IOException {
String filename = resource.getFilename();
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
return (Map) PropertiesLoaderUtils.loadProperties(resource);
}
return new OriginTrackedPropertiesLoader(resource).load();
}
}
OriginTrackedPropertiesLoader类
此类作用:将含”.properties“结尾的文件加载到map中,当然也支持list类型。
public Map<String, OriginTrackedValue> load(boolean expandLists) throws IOException {
try (CharacterReader reader = new CharacterReader(this.resource)) {
}
...
}
其中load()方法中CharacterReader的字符类型指定为ISO_8859_1格式。
CharacterReader(Resource resource) throws IOException {
this.reader = new LineNumberReader(new InputStreamReader(
resource.getInputStream(), StandardCharsets.ISO_8859_1));
}
从这里就可以知道为何会出现乱码了。
解决办法
以下方法都可以解决乱码问题。
用apollo直接配置中文的内容
直接在apollo客户端配置中文字符,则可以解决。
这次我直接用的这个办法,方便快捷。
用new String()来转换为UTF-8
代码如下:
String utf8Content = new String(content.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8)
注意点
此处在配置时如果用到了apollo,后续变更变量内容,直接在apollo中修改,则在转换时因apollo已经转换为了utf-8,则会出现转换问题。
在启动类配置@PropertySource并指定配置文件和UTF-8格式
其实就是@PropertySource注解指定了配置文件和编码格式。
在启动类中加上以下配置:
@PropertySource(value = "classpath:test.properties", encoding="UTF-8")
然后新增一个test.properties配置文件,将此配置写到mystyle.station.content这个配置即可。
特别说明:
新增的配置文件不能用application.properties,否则还是乱码。
.yml/.yaml默认采用UTF-8加载
将yml/yaml文件设置为UTF-8的编码格式,springboot读该文件即采用UTF-8编码。
查看源码可知,初始化时会确定文件的编码格式。首先读取BOM(Byte Order Mark)文件头信息,如果头信息中有UTF8/UTF16BE/UTF16LE就采用对应的编码,没有或者不是则采用UTF8编码。
完美解决!
参考和推荐文章
边栏推荐
猜你喜欢
随机推荐
[QNX] Command
MYSQL的下载与配置 mysql远程操控
Let torch cuda. is_ Experience of available() changing from false to true
Take you to resolve hash conflicts and implement a simple hash table,
Applet setting button sharing function
Detailed explanation of MySQL mvcc mechanism
A little experience of next (ITER (dataloader))
数字签名标准(DSS)
将字符串B插入字符串A,有多少种插入办法可以使新串是一个回文串
ros::spinOnce()和ros::spin()的使用和区别
JVM entry door (1)
sql 中的alter操作总结
带你解决哈希冲突,并实现一个简单hash表,
ISO文件
数据加密标准DES安全性
Interview key points that must be mastered index and affairs (with B-tree and b+ tree)
Deep understanding of MySQL lock and transaction isolation level
股票开账户如何优惠开户?现在在线开户安全么?
JVM entry Door (1)
Padding percentage operation








