読者です 読者をやめる 読者になる 読者になる

なみひらブログ

学んだことを日々記録する。~ since 2012/06/24 ~

SpringFrameworkで多言語を扱うときの実装メモ

背景

  • SpringFrameworkを使って多言語対応する際の実装をメモっときます。
  • ブラウザやクライアントの言語によって返すJSONの内容を変えたいときなどに利用します。
  • 今回はWebAPI用のメモです。Viewでの多言語対応はまた別途記載します。
    • 例:
(言語指定:英語のとき)
{
  "name" : "Tokyo"
}

(言語指定:日本語のとき)
{
  "name" : "東京"
}


前提

  • springは4.1.4.RELEASEを使っています。*1
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

対応メモ

多言語リソースファイルを用意する

各言語での用語を定義するファイルを用意する。

    • 例:resources/i18n/messages.properties
      • デフォルトとなる言語ファイル。用意されていない言語についてはこの言語ファイルの値が適用される
city.name.tokyo=Tokyo
    • 例:resources/i18n/messages_ja.properties
      • Localeが日本語のときに適用される言語ファイル
city.name.tokyo=東京

SpringにMessageSourceのbeanを登録する

Springにて多言語が扱えるために、使うクラスをbean登録する。

  • 例:spring-context.xml
    • 特記事項
      • 使うクラスはResourceBundleMessageSource(変更を動的に適用してくれない)か、ReloadableResourceBundleMessageSource(変更を動的に適用してくれる)。
      • "basename"は多言語リソースのファイル名。
      • なぜか「classpath:i18n/messages」や「/WEB-INF/i18n/messages」のような記載ができない(;´Д`)相対パスで記載する。
<!-- i18n -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
	<property name="basename" value="i18n/messages" />
	<property name="defaultEncoding" value="utf-8" />
</bean>

コントローラに適用する

言語を受け取って、その言語によってレスポンスの内容を返すコントローラの例。

  • 特記事項
    • "messageSource":先ほどbean登録したMessageSourceをコントローラにDIする。
    • Locale locale:コントローラの引数にLocaleを指定すると、Springがクライアントの指定した言語情報を渡してくれる(Accept-Languageから特定された言語)
    • messageSource.getMessageでメッセージキーとロケール情報を渡して対応する値が返ってくる。
@RestController
public class CityApiController {

    @Autowired
    private MessageSource messageSource;

    @RequestMapping(value = "/api/cities/{id}", method = GET)
    public City get(Locale locale, @PathVariable int id) {
        final City city = new City();
        city.setName(messageSource.getMessage("city.name." + id, null, locale));
        return city;
    }
}

まとめ

  • 意外と簡単(*´Д`*)

参考

*1: 本記事で4.1の機能を出し切っていない可能性はある(;´Д`)