15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Frameworkの多国語対応

Posted at

はじめに

Spring Frameworkでの多国語対応について調べていたがいくつか詰まったところがあったのでメモ。
なおSpring Bootのバージョンは2.1.2。

基本

基本的にはorg.springframework.context.MessageSourceを使う。

設定ファイル例

src/main/resourcesの直下に以下のようなファイルを作成する。

messages.properties
hello=hello
messages_ja.properties
hello=こんにちは

messages.propertiesがデフォルトのファイルで、messages_ja.propertiesが日本語用のファイル(アンダーバー以降でロケールを指定)。

呼び出し例

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

MessageSourceをインジェクションしてメッセージを呼び出す。上記サンプルでは基本的なやつを使っているが、公式ではデフォルトメッセージを指定するメソッドなんかもある。

実行例

Accept-LanguagejaにしてGETリクエストを送信してやればこんにちはが、それ以外の言語(en-USzh-CN等)でリクエストを送信してやればhelloが返ってくる。
ただし環境によってはja以外にしてもhelloが返ってこない場合がある(後述)。

応用

設定ファイルの場所や名前を変更したい

デフォルトだとmessages.propertiesを参照するが、ファイルの場所を変更したり複数用意したりしたい場合がある。
その場合はインジェクションされるMessageSourceを修正してやればいい。

設定ファイル例

messages.propertiesの内容はそのままで、保存場所をsrc/main/resources/i18nにしたとする。
また、新規で以下のファイルをsrc/main/resources/i18n/hogeに保存したとする。

hoge.properties
hoge=hoge
hoge_ja.properties
hoge=ほげ

Spring Framework側での設定例

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

ResourceBundleMessageSourceMessageSourceを実装したクラス。他にもメッセージファイルをリロードできるReloadableResourceBundleMessageSourceなんかがあるらしい。
setBasenamesでメッセージファイルの場所や名前を指定する。
application.propertiesでメッセージファイルを指定する方法もあるらしいが未確認。

呼び出し例

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

実行例

基本のときと同じでAccept-Languageの値によって日本語(こんにちはほげ)が返ってきたり、hellohogeが返ってくる。

補足

常に日本語でメッセージが返る場合

大抵どのサイトでMessageSourceのことを調べても指定されたロケールがなければデフォルトファイルのメッセージが返されるとあるが、ローカルPCで確認すると常に日本語でメッセージが返ってきた。
調べた限りロケールが存在しなかった場合デフォルトだとシステムロケールにフォールバックされるらしい(参考)。ローカルPCで確認したときはシステムロケールが日本語で、かつ日本語のプロパティファイルを用意していたため常に日本語でメッセージが返ってきたのだと予想。

対策

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

setFallbackToSystemLocalefalseにしてやれば指定されたロケールのファイルが存在しなかった場合(システムロケール等関係なく)デフォルトのファイルのメッセージが返ってくるようになる。

おわりに

jaだと日本語で返ってくるがja_JPだと日本語で返ってこなかったり等まだいじれそうなところはあったのでどこかで調査したい。

15
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?