当前位置:网站首页>Successfully solved the problem of garbled microservice @value obtaining configuration file

Successfully solved the problem of garbled microservice @value obtaining configuration file

2022-06-26 18:41:00 JobsTribe

Problem description

Get... From microservices properties when :

mystyle.station.content =  Test Chinese characters 

Related codes :

@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";
    }
}

In use @Value There is a garbled code problem when getting the value .

GetPropertiesValueDemo_getCreateContent starts,content:å°Šæ•¬çš„ç”¨æˆ·ï¼Œæ‚¨çš„æ‰‹æœºå·²æ¬ è´¹ï¼Œè¯·æ‚¨åŠæ—¶äº¤è´¹ã€‚è¯¦æƒ
请拨打<电话>。 

Cause analysis

Conclusion

Through source code analysis and related articles, you can know ,application.properties The default is ISO-8859-1 Format to load .

The path to view the source code is as follows : Bottom source jar Package for :

  • org.springframework.boot:spring-boot:2.1.3.RELEASE

View the relevant code order of the class :

ConfigFileApplicationListener loadDocuments -->PropertySourceLoader load --> PropertiesPropertySourceLoader loadProperties -->OriginTrackedPropertiesLoader load --> OriginTrackedPropertiesLoader CharacterReader 

The specific source code analysis is as follows :

ConfigFileApplicationListener class

The address of the class is :org.springframework.boot.context.config.

This kind of effect : Load configuration file properties , Can be loaded ”application.properties“ and ”application.yml“ File properties of , You can also load the file to get the activity configuration .

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 class

This kind of effect : take ”.properties“ File loading to PropertySource in .

Differentiated call yes .xml The end of the file is another file type , Then we call different methods .

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 class

This kind of effect : Will contain ”.properties“ The end file is loaded into map in , Yes, of course list type .

public Map<String, OriginTrackedValue> load(boolean expandLists) throws IOException {
    
		try (CharacterReader reader = new CharacterReader(this.resource)) {
    }
  	...
}

among load() In the method CharacterReader The character type of is specified as ISO_8859_1 Format .

CharacterReader(Resource resource) throws IOException {
    
			this.reader = new LineNumberReader(new InputStreamReader(
					resource.getInputStream(), StandardCharsets.ISO_8859_1));
		}

From here, we can know why there is garbled code .

terms of settlement

The following methods can solve the problem of garbled code .

use apollo Configure Chinese content directly

Directly in apollo The client is configured with Chinese characters , It can solve the problem .

This time I used this method directly , Convenient and quick .

use new String() To convert to UTF-8

The code is as follows :

String utf8Content = new String(content.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8)

Be careful

If... Is used during configuration here apollo, Subsequent changes to variable contents , Directly in apollo Revision in China , Then, at the time of conversion apollo Has been converted to utf-8, There will be conversion problems .

In the startup class configuration @PropertySource And specify the configuration file and UTF-8 Format

In fact, that is @PropertySource Annotations specify the configuration file and encoding format .

Add the following configuration to the startup class :

@PropertySource(value = "classpath:test.properties", encoding="UTF-8")

Then add a new test.properties The configuration file , Write this configuration to mystyle.station.content This configuration will do .

In particular

The newly added configuration file cannot be used application.properties, Otherwise, it is still garbled .

.yml/.yaml By default UTF-8 load

take yml/yaml The file is set to UTF-8 The encoding format of ,springboot Read this file using UTF-8 code .

See the source code , The encoding format of the file will be determined during initialization . Read first BOM(Byte Order Mark) File header information , If there is... In the header UTF8/UTF16BE/UTF16LE Use the corresponding code , If there is no or no, use UTF8 code .

Perfect solution !

Reference and recommended articles

SpringBoot Use @Value Read .properties Chinese garbled code and its solution

原网站

版权声明
本文为[JobsTribe]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206261809249518.html