38

In my application.properties I add some custom attributes.

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

In this class I have the representation of the custom attributes.

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

And here I use my 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();
        }
    }

While debugging I can see that my this.getSubjectMessage() variable has this value inside: This is a ä ö ü à problem. So before sending my mail I already have an UTF-8 encoding problem.

I already checked the encoding of the application.properties file and its UTF-8.

My IDE(STS/Eclipse) and the project properties are also set on UTF-8.

How can I set the UTF-8 encoding for the text of my custom attributes in the application.properties file?

Patrick
  • 12,336
  • 15
  • 73
  • 115
  • 2
    I remember reading somewhere that Java expects that `*.properties` files are encoded in ISO-8859-1 and that's why Spring treats `application.properties` as if it's in ISO-8859-1. See this question: [Spring Boot default properties encoding change?](http://stackoverflow.com/questions/27882191/spring-boot-default-properties-encoding-change). Possible solution: Use YAML instead of properties files. – Jesper May 25 '16 at 12:57
  • @Jesper yes, I checked this answer, too. Still hoping there is maybe another solution for properties files. – Patrick May 25 '16 at 13:09

5 Answers5

28

As already mentioned in the comments .properties files are expected to be encoded in ISO 8859-1. One can use unicode escapes to specify other characters. There is also a tool available to do the conversion. This can for instance be used in the automatic build so that you still can use your favorite encoding in the source.

Be sure to read also the other answers for some alternatives. There are ways to specify the encoding for properties.

Henry
  • 42,982
  • 7
  • 68
  • 84
  • 3
    Awesome, thank you, but this answer would be better with an example of how the encoded characters should look like in application.properties: custom.mail.property.subject-message=This is a \u00E4 \u00F6 \u00FC \u00DF problem – hipokito Apr 10 '19 at 10:08
  • 2
    Find a online conversion tool here: https://native2ascii.net/ – Datz Jun 09 '21 at 19:09
  • Sure, if you need to add an odd "Mötley Crüe" here or there conversion works. If, like most of the world, you find yourself not speaking English as a mother tongue, you need something more stable... I opted to use `application.xml` and Java's XML format for properties (https://www.baeldung.com/java-properties). Also see other answers here where, hopefully, we've been able to establish where the `@PropertySource` attribute should go... – Erk Jul 23 '21 at 04:19
  • Is it only way to convert asci our special character like İ Ş to use properties file or is there another way to that? – Bilgehan Jan 05 '22 at 08:58
  • You should update since that isn't true anymore with recents version of Java – pdem Jan 28 '22 at 14:39
25

Please, try to add PropertySource annotation with encoding parameter into your Configuaration file:

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

Hope it helps.

May12
  • 2,420
  • 12
  • 63
  • 99
  • 1
    Absolutely fits) – Frankie Drake Oct 24 '18 at 09:02
  • And where, pray tell, do you add this annotation? – Erk Jul 23 '21 at 04:14
  • 2
    @Erk good question. the dark magic alchemy of the spring boot docs says the following: Add it to the `@Configuration`-class: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/PropertySource.html – kiltek Jul 28 '22 at 11:48
14

I've faced with the same problem. In Spring Boot there are 2 PropertySourceLoader which are used to load properties in application:

  • PropertiesPropertySourceLoader - supports UTF-8 only when load from XML
  • YamlPropertySourceLoader - supports UTF-8, but you have to change configuration format to use it

They're listed in the file https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/resources/META-INF/spring.factories

So we decided to write our own implementation of PropertySourceLoader which would be able to load properties from UTF-8 file correctly. The idea is from answer @BalusC - How to use UTF-8 in resource properties with ResourceBundle

Our PropertySourceLoader implementation:

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

}

Then we created file resources/META-INF/spring.factories with content:

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

Now we have 3 PropertySourceLoader in our application in following order:

  • UnicodePropertiesPropertySourceLoader
  • PropertiesPropertySourceLoader
  • YamlPropertySourceLoader

NOTES!

  1. I'm not sure that it is proper usage of PropertyResourceBundle
  2. I'm not sure that order of PropertySourceLoaders in Spring Boot will be the same if you make a dedicated library to reuse it in other projects.

In our project this solution works fine.

UPDATE!

It's better to implement load method of UnicodePropertiesPropertySourceLoader without PropertyResourceBundle:

@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;
}
Community
  • 1
  • 1
merz
  • 208
  • 1
  • 8
8

just converted the text with the special chars with https://native2ascii.net/

gischy
  • 154
  • 1
  • 7
5

To set the UTF-8 encoding for the text in the application.properties (and any other Java properties as well as environment variables) add -Dfile.encoding=UTF-8 to java command line agrs.

Aleksey
  • 51
  • 1
  • 2
  • 1
    I don't think this is that simple, especially before Java 9 – Jidehem Sep 13 '18 at 13:18
  • Yes, it is. I use this flag for Spring to read application.properties and system environment variables in unicode with Java 8. For example IDEA adds this flag automatically. ```/usr/java/jdk1.8.0_181/bin/java ... -Dfile.encoding=UTF-8 -classpath ... test.hello.TestHello``` – Aleksey Sep 14 '18 at 07:43
  • 2
    As a side effect Java application running in Docker container with ```-Dfile.encoding=UTF-8``` produces readable output in unicode instead of question marks. So, this magic flag fixes both problems without any line on code. There is a related topic explaining some details https://stackoverflow.com/questions/361975/setting-the-default-java-character-encoding – Aleksey Sep 14 '18 at 07:53