Spring-Boot 中 application.properties 属性的 UTF-8 编码

Posted

技术标签:

【中文标题】Spring-Boot 中 application.properties 属性的 UTF-8 编码【英文标题】:UTF-8 encoding of application.properties attributes in Spring-Boot 【发布时间】:2016-09-23 01:05:36 【问题描述】:

在我的application.properties 中,我添加了一些自定义属性。

custom.mail.property.subject-message=This is a ä ö ü ß problem

在这个类中,我有自定义属性的表示。

@Component
@ConfigurationProperties(prefix="custom.mail.property")
public class MailProperties 
    private String subjectMessage;
    public String getSubjectMessage() 
        return subjectMessage;
    
    public void setSubjectMessage(String subjectMessage) 
        this.subjectMessage = subjectMessage;
    

我在这里使用我的MailProperties

@Service
public class SimpleUnknownResponseMessage extends MailProperties implements UnknownResponseMessage

    private JavaMailSender javaMailSender;

    @Autowired
    public SimpleUnknownResponseMessage(JavaMailSender javaMailSender) 
        this.javaMailSender = javaMailSender;
    

    @Override
    public void placeUnknownResponse(BookResponse bookResponse) 
        MimeMessage message = javaMailSender.createMimeMessage();
        try 
            MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8");
            helper.setSubject(this.getSubjectMessage());            
            javaMailSender.send(message);

         catch (MessagingException e) 
            e.printStackTrace();
        
    

调试时我可以看到我的this.getSubjectMessage() 变量内部有这个值:This is a ä ö ü à problem。所以在发送邮件之前,我已经遇到了 UTF-8 编码问题。

我已经检查了application.properties 文件的编码及其 UTF-8。

我的 IDE(STS/Eclipse) 和项目属性也设置为 UTF-8。

如何为 application.properties 文件中的自定义属性的文本设置 UTF-8 编码?

【问题讨论】:

我记得在某处读到 Java 期望 *.properties 文件以 ISO-8859-1 编码,这就是 Spring 将 application.properties 视为 ISO-8859-1 的原因。看到这个问题:Spring Boot default properties encoding change?。可能的解决方案:使用 YAML 而不是属性文件。 @Jesper 是的,我也检查了这个答案。仍然希望属性文件可能有另一种解决方案。 【参考方案1】:

正如 cmets 中已经提到的,.properties 文件预计将使用 ISO 8859-1 进行编码。可以使用 unicode 转义符来指定其他字符。还有一个tool 可用于进行转换。例如,这可以在自动构建中使用,以便您仍然可以在源代码中使用您喜欢的编码。

【讨论】:

太棒了,谢谢,但是如果有一个例子来说明编码字符在 application.properties 中的样子,这个答案会更好: custom.mail.property.subject-message=这是一个 \u00E4 \u00F6 \u00FC \u00DF问题 在此处查找在线转换工具:native2ascii.net 当然,如果您需要在这里或那里添加一个奇怪的“Mötley Crüe”转换作品。如果像世界上大多数人一样,您发现自己的母语不是英语,那么您需要更稳定的东西……我选择使用application.xml 和Java 的XML 格式的属性(baeldung.com/java-properties)。另请参阅此处的其他答案,希望我们能够确定 @PropertySource 属性应该去哪里... 将 asci 我们的特殊字符(如 İŞ)转换为使用属性文件的唯一方法还是有其他方法?【参考方案2】:

请尝试将带有编码参数的PropertySource注释添加到您的配置文件中:

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

希望对您有所帮助。

【讨论】:

绝对合适) 请问您在哪里添加此注释?【参考方案3】:

我也遇到过同样的问题。 在 Spring Boot 中有 2 个 PropertySourceLoader 用于在应用程序中加载属性:

PropertiesPropertySourceLoader - 仅在从 XML 加载时支持 UTF-8 YamlPropertySourceLoader - 支持 UTF-8,但您必须更改配置格式才能使用它

它们在文件https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/resources/META-INF/spring.factories中列出

所以我们决定编写自己的 PropertySourceLoader 实现,它能够正确地从 UTF-8 文件加载属性。这个想法来自答案@BalusC - How to use UTF-8 in resource properties with ResourceBundle

我们的 PropertySourceLoader 实现:

public class UnicodePropertiesPropertySourceLoader implements PropertySourceLoader 

@Override
public String[] getFileExtensions() 
    return new String[]"properties";


@Override
public PropertySource<?> load(String name, Resource resource, String profile) throws IOException 
    if (profile == null) 
        Properties properties = new Properties();
        PropertyResourceBundle bundle = new PropertyResourceBundle(new InputStreamReader(resource.getInputStream(), "UTF-8"));
        Enumeration<String> keys = bundle.getKeys();
        while (keys.hasMoreElements()) 
            String key = keys.nextElement();
            properties.setProperty(key, bundle.getString(key));
        
        if (!properties.isEmpty()) 
            return new PropertiesPropertySource(name, properties);
        
    
    return null;



然后我们创建了文件 resources/META-INF/spring.factories,其内容为:

# Custom PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
your.own.package.UnicodePropertiesPropertySourceLoader

现在我们的应用程序中有 3 个 PropertySourceLoader,顺序如下:

UnicodePropertiesPropertySourceLoader PropertiesPropertySourceLoader YamlPropertySourceLoader

注意!

    我不确定是否正确使用 PropertyResourceBundle 如果您创建一个专用库以在其他项目中重用它,我不确定 Spring Boot 中 PropertySourceLoaders 的顺序是否相同。

在我们的项目中,这个解决方案运行良好。

更新!

最好在没有PropertyResourceBundle的情况下实现UnicodePropertiesPropertySourceLoader的加载方法:

@Override
public PropertySource<?> load(String name, Resource resource, String profile) throws IOException 
    if (profile == null) 
        Properties properties = new Properties();
        properties.load(new InputStreamReader(resource.getInputStream(), "UTF-8"));
        if (!properties.isEmpty()) 
            return new PropertiesPropertySource(name, properties);
        
    
    return null;

【讨论】:

【参考方案4】:

要为 application.properties(以及任何其他 Java 属性以及环境变量)中的文本设置 UTF-8 编码,请将 -Dfile.encoding=UTF-8 添加到 java 命令行 agrs。

【讨论】:

我不认为这很简单,尤其是在 Java 9 之前 是的。我在 Spring 中使用这个标志来读取带有 Java 8 的 unicode 中的 application.properties 和系统环境变量。例如,IDEA 会自动添加这个标志。 /usr/java/jdk1.8.0_181/bin/java ... -Dfile.encoding=UTF-8 -classpath ... test.hello.TestHello 作为一个副作用,Java 应用程序在 Docker 容器中运行,-Dfile.encoding=UTF-8 会以 unicode 而不是问号生成可读的输出。所以,这个神奇的标志在没有任何代码行的情况下解决了这两个问题。有一个相关主题解释了一些细节***.com/questions/361975/…【参考方案5】:

刚刚用https://native2ascii.net/ 转换了带有特殊字符的文本

【讨论】:

以上是关于Spring-Boot 中 application.properties 属性的 UTF-8 编码的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot 中application.properties的各种配置

spring-boot结合maven配置不同环境的profile

如何 JUnit 测试 Spring-Boot 的 Application.java

如何在spring-boot中用application.properties制作config类?

如何在 spring-boot 配置中加载 application.yaml 配置以进行硒测试

spring-boot默认的application.properties属性