[JAVA] Spring Framework multilingual support

Introduction

I was investigating multilingual support in Spring Framework, but there were some clutters, so I made a note. The version of Spring Boot is 2.1.2.

Basic

Basically, use ʻorg.springframework.context.MessageSource`.

Configuration file example

Create the following files directly under src / main / resources.

messages.properties


hello=hello

messages_ja.properties


hello=Hello

messages.properties is the default file, and messages_ja.properties is the file for Japanese (specify the locale after the underscore).

Call example

MessageController.java


@CrossOrigin
@RestController
@RequestMapping("/messages")
public class MessageController {
	@Autowired
	private MessageSource messageSource;

	@GetMapping("/hello")
	public String hello(Locale locale) {
		return messageSource.getMessage("hello", new String[] {}, locale);
	}
}

Inject MessageSource to call the message. The above sample uses the basic one, but in Official the default message There is also a method to specify.

Execution example

Accept-Language the ja in to do it by sending a GET requestHellois, other languages ( en-US and zh-CN, etc.)do it by sending a request by helloIs returned. However, depending on the environment, hello may not be returned even if it is not ja ([described later](# when the message is always returned in Japanese)).

application

I want to change the location and name of the configuration file

By default, it refers to messages.properties, but you may want to change the location of the file or prepare multiple files. In that case, modify the injected MessageSource.

Configuration file example

Suppose you keep the contents of messages.properties and set the save location to src / main / resources / i18n. Also, assume that the following new files are saved in src / main / resources / i18n / hoge.

hoge.properties


hoge=hoge

hoge_ja.properties


hoge=Hoge

Setting example on the Spring Framework side

MessageSourceConfig.java


@Configuration
public class MessageSourceConfig {
	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setBasenames("i18n/messages", "i18n/hoge/hoge");
		messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
		return messageSource;
	}
}

A class in which ResourceBundleMessageSource implements MessageSource. There seems to be another ReloadableResourceBundleMessageSource that can reload the message file. Specify the location and name of the message file with setBasenames. There seems to be a way to specify the message file in ʻapplication.properties`, but it is unconfirmed.

Call example

MessageController.java


@CrossOrigin
@RestController
@RequestMapping("/messages")
public class MessageController {
	@Autowired
	private MessageSource messageSource;

	@GetMapping("/hello")
	public String hello(Locale locale) {
		return messageSource.getMessage("hello", new String[] {}, locale);
	}

	@GetMapping("/hoge")
	public String hoge(Locale locale) {
		return messageSource.getMessage("hoge", new String[] {}, locale);
	}
}

Execution example

[Basic] by the same a Accept-Language of value as when the (# execution example) or returned Japanese (HelloandHoge) is, hello and hoge is returned.

Supplement

When the message is always returned in Japanese

Most of the time, when I looked up MessageSource on any site, it said that the message of the default file was returned if there was no specified locale, but when I checked it on my local PC, the message was always returned in Japanese. As far as I checked, it seems that if the locale does not exist, it will fall back to the system locale by default (Reference context / support / AbstractResourceBasedMessageSource.html # setFallbackToSystemLocale-boolean-)). When I checked it on my local PC, I expected that the message was always returned in Japanese because the system locale was Japanese and the property file in Japanese was prepared.

Countermeasures

MessageSourceConfig.java


@Configuration
public class MessageSourceConfig {
	@Bean
	public MessageSource messageSource() {
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setBasenames("i18n/messages", "i18n/hoge/hoge");
		messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
		messageSource.setFallbackToSystemLocale(false);
		return messageSource;
	}
}

If you set setFallbackToSystemLocale to false, the message of the default file will be returned if the file of the specified locale does not exist (regardless of the system locale etc.).

in conclusion

If it is ja, it will be returned in Japanese, but if it is ja_JP, it will not be returned in Japanese, etc. There were still some places that I could mess with, so I would like to investigate somewhere.

Recommended Posts

Spring Framework multilingual support
[Spring Framework] Configuration split
1. Start Spring framework from 1
Spring Framework Summary-About DI
[Personal memo] About Spring framework
Spring Framework self-study memo series_1
About Spring Framework context error
Spring Framework 5.0 Summary of major changes
spring framework Simple study memo (2): AOP
Java --Jersey Framework vs Spring Boot
Spring Framework tools for Java developer
Test Spring framework controller with Junit
Introducing Basic Authentication on Heroku [Spring Framework]
Support Protocol Buffers for Spring Cloud Stream
Major changes related to Spring Framework 5.0 Test
Spring Framework bean definition XML: custom tag
Why spring consider as a lightweight framework
Spring Framework study notes [Part 1] DI container
About the initial display of Spring Framework
Null support cache in Spring Data Redis
Major changes in Spring Framework 5.0 core functionality
Features of spring framework for java developers