Description
Versions
Spring Boot Version 2.7.2
Overview
(I'm sorry ,The English translation comes from the search engine Bing.com )
I was migrating the previous Spring application to the current SpringBoot application, and I found that the encoding of application.properties was ISO_8859_1, so I customized the chaset to UTF-8, but because SpringBoot's class PropertiesPropertySourceLoader is not convenient to inherit, I can only use the ugly inheritance implementation to set (Copy OriginTrackedPropertiesLoader.java to my customized java file). It is therefore expected that class plus an extended feature that allows the specified encoding to be used makes it easy to customize the character set using a concise inheritance implementation.
config in Spring application:
java code :
@PropertySource(value = "classpath:application.properties", encoding = "UTF-8")
or xml code:
<context:property-placeholder location="classpath:application.properties" file-encoding="UTF-8"/>
My custom extension steps are as follows:
-
go to https://start.spring.io/ , generate a gradle project with Java 8 and SpringBoot 2.7.2.
-
add chinese value to application.properties,just like follow:
testCnVal = 测试中文
testCnValUcode = \u6D4B\u8BD5\u6C49\u5B57
testArrayVal[] = a,b,c
- write test code to get value,just like follow:
@Service
public class PropTestBean {
@Value("${testCnVal}")
private String testCnVal;
@Value("${testCnValUcode}")
private String testCnValUcode;
@Value("${testArrayVal[1]}")
private String testArrayVal1;
@EventListener
void onRefreshEvent(ContextRefreshedEvent event) {
System.out.println("testCnVal==" + testCnVal);
System.out.println("testCnValUcode==" + testCnValUcode);
System.out.println("testArrayVal1==" + testArrayVal1);
Environment env = event.getApplicationContext().getEnvironment();
System.out.println("find key|testArrayVal=" + env.containsProperty("testArrayVal"));
System.out.println("find key|testArrayVal[]=" + env.containsProperty("testArrayVal[]"));
System.out.println("find key|testArrayVal[1]=" + env.containsProperty("testArrayVal[1]"));
System.out.println("testArrayVal==" + env.getProperty("testArrayVal[]"));
System.out.println("testArrayVal2==" + env.getProperty("testArrayVal[2]"));
}
}
-
run the main class PropertiesdemoApplication,then see the value is not right:
-
copy PropertiesPropertySourceLoader's code and OriginTrackedPropertiesLoader's code to my customized class UglyUTF8PropertiesPropertySourceLoader:
-
change StandardCharsets.ISO_8859_1 to StandardCharsets.UTF_8 in OriginTrackedPropertiesLoader.CharacterReader's construct method
CharacterReader(Resource resource) throws IOException {
reader = new LineNumberReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
}
- write config to src/main/resources/META-INF/spring.factories:
org.springframework.boot.env.PropertySourceLoader=com.lizongbo.propertiesdemo.UglyUTF8PropertiesPropertySourceLoader
Refactored sample code
So I expect to expose the parameters that can be extended to the settings, and the other logic reuses the current code. So I've given an example of the refactored code under com.lizongbo.propertiesdemo.boot.env, adding the following variables
public class PropertiesPropertySourceLoader implements PropertySourceLoader {
// default charset
protected Charset charset = StandardCharsets.ISO_8859_1;
protected boolean expandLists = true;
private static final String XML_FILE_EXTENSION = ".xml";
public Charset getCharset() {
return charset;
}
public boolean isExpandLists() {
return expandLists;
}
Then my customized extend class is very simple:
public class UTF8PropertiesPropertySourceLoader extends PropertiesPropertySourceLoader {
public Charset getCharset() {
return StandardCharsets.UTF_8;
}
public boolean isExpandLists() {
return true;
}
}
refactored code diff :
the demo project in the attach file:
Steps to Reproduce
- import the demo project to ide.
- run the main class PropertiesdemoApplication.
- see console output info.
- see spring.factories
- review com.lizongbo.propertiesdemo.boot.env's code.