Springでの国際化対応(i18n)を徹底解説!実装方法と注意点

Springフレームワークは、企業規模のアプリケーションから小規模なWebアプリケーションまで幅広く使われているJavaベースのアプリケーションフレームワークです。グローバル展開を目指すアプリケーションでは、異なる言語や地域ごとの文化に対応する国際化(i18n)が重要な課題となります。国際化とは、アプリケーションが異なる言語やロケール(国・地域設定)に適応できるように設計されることを指します。

本記事では、Springを使ったJavaアプリケーションで国際化対応を実現するための具体的な方法について、ステップごとに解説します。メッセージの翻訳や日付・数値のフォーマット対応など、実装における重要なポイントを取り上げ、Springの国際化機能を効率的に活用する方法を紹介します。

目次
  1. 国際化対応(i18n)の基本概念
    1. なぜ国際化が重要か
    2. ローカリゼーションとの違い
    3. Springにおける国際化対応のメリット
  2. Springにおける国際化対応の仕組み
    1. MessageSourceによるメッセージ管理
    2. LocaleResolverによるロケールの管理
    3. Spring Bootでの国際化の簡略化
  3. メッセージプロパティファイルの作成
    1. プロパティファイルの命名規則
    2. プロパティファイルの内容例
    3. プロパティファイルの配置場所
    4. プロパティファイルにおけるエスケープ文字の使用
  4. メッセージソースの設定方法
    1. MessageSourceとは
    2. MessageSourceの設定手順
    3. Spring BootでのMessageSource設定
    4. メッセージの取得方法
    5. デフォルトメッセージの設定
  5. Webアプリケーションでの国際化の実装
    1. Spring MVCにおける国際化の基本的な流れ
    2. 1. メッセージプロパティファイルの準備
    3. 2. MessageSourceの設定
    4. 3. LocaleResolverの設定
    5. 4. ビューでのメッセージ表示
    6. 動的なロケール切り替え
  6. コントローラでのメッセージ取得
    1. MessageSourceを使ったメッセージの取得
    2. コントローラでの処理内容
    3. 例:ビューでのメッセージ表示
    4. 動的パラメータの使用
    5. 例外時のデフォルトメッセージ
  7. リクエストに基づく言語切替方法
    1. LocaleResolverを使用した言語切替
    2. SessionLocaleResolverによる設定例
    3. HandlerInterceptorを使った動的言語切替
    4. LocaleChangeInterceptorの登録
    5. URLでの言語指定
    6. CookieLocaleResolverによる言語の永続化
    7. まとめ
  8. Spring Bootでの国際化対応の設定
    1. 1. メッセージプロパティファイルの配置
    2. 2. application.propertiesでの設定
    3. 3. LocaleResolverの設定
    4. 4. リクエストによる言語切替
    5. 5. ビューでのメッセージ表示
    6. 6. カスタムメッセージの利用
    7. まとめ
  9. 日付や数値フォーマットの国際化対応
    1. 1. Springでの日付フォーマット
    2. 2. Springでの数値フォーマット
    3. 3. Formatterクラスを使用したカスタムフォーマット
    4. 4. application.propertiesでのデフォルトフォーマット設定
    5. 5. ロケールごとのカスタムフォーマット
    6. まとめ
  10. 国際化対応における注意点
    1. 1. メッセージキーの一貫性を保つ
    2. 2. プロパティファイルのエンコーディング
    3. 3. メッセージのコンテキストを意識する
    4. 4. 動的パラメータの管理
    5. 5. デフォルトメッセージの設定
    6. 6. 多言語対応のテスト
    7. まとめ
  11. まとめ

国際化対応(i18n)の基本概念

国際化(Internationalization、略してi18n)は、ソフトウェアやWebアプリケーションを異なる言語や地域設定に適応させるためのプロセスです。i18nという略称は、”Internationalization”の頭文字 “I” と末尾の “N” の間に18文字があることから由来しています。

なぜ国際化が重要か

国際化対応は、グローバル市場においてアプリケーションを展開する際に不可欠です。異なる国や地域のユーザーが自分の言語や文化に合わせたインターフェースを利用できることで、アプリケーションの使用感が向上し、顧客満足度も高まります。国際化対応が不十分だと、ユーザーが使いにくいと感じ、ビジネスの成長にも悪影響を及ぼす可能性があります。

ローカリゼーションとの違い

国際化とよく混同される概念に「ローカリゼーション」があります。国際化はアプリケーションが異なる言語や文化に対応できるようにするための設計や準備を指し、ローカリゼーション(Localization、略してL10n)は、実際に特定の言語や地域向けにアプリケーションを適応させるプロセスです。たとえば、国際化は英語、フランス語、スペイン語など複数言語に対応できる仕組みを構築し、ローカリゼーションはその仕組みを使って特定の言語(例:フランス語)の翻訳や設定を行います。

Springにおける国際化対応のメリット

Springフレームワークを使用すると、国際化対応が非常にスムーズに行えます。Springは、メッセージの翻訳やロケールごとの設定を管理する機能を提供しており、設定次第で簡単に言語の切り替えが可能です。これは、グローバルなユーザーベースを持つアプリケーションにとって大きなメリットとなります。

Springにおける国際化対応の仕組み

Springフレームワークは、国際化対応を簡単に実装するための豊富な機能を提供しています。特に、MessageSourceLocaleResolverなどのクラスを使って、言語ごとのメッセージ管理やユーザーの言語設定に基づいた表示を実現することが可能です。

MessageSourceによるメッセージ管理

Springでは、国際化対応のためにMessageSourceインターフェースを使用します。このインターフェースを実装することで、アプリケーション内で使用されるメッセージやラベルを外部のプロパティファイルから取得できるようになります。MessageSourceは、リクエストされたロケールに応じて適切なメッセージを返す役割を担います。

例えば、messages.propertiesという名前のファイルをデフォルトのメッセージファイルとし、messages_en.propertiesmessages_fr.propertiesといったファイルを追加することで、英語やフランス語などの言語に対応できます。Springは、ユーザーのロケールに基づいてこれらのファイルから適切なメッセージを自動的に選択します。

LocaleResolverによるロケールの管理

Springでは、ユーザーのロケール(言語や地域の設定)を管理するためにLocaleResolverを使用します。LocaleResolverは、ユーザーのリクエストに基づいて適切なロケールを判定し、それに応じたメッセージやフォーマットを提供します。

代表的なLocaleResolverには以下のようなものがあります:

  • SessionLocaleResolver:ユーザーのセッションにロケールを保存し、セッション間でロケールを維持します。
  • CookieLocaleResolver:ユーザーのロケールをクッキーに保存し、次回のリクエスト時に同じロケールを適用します。
  • AcceptHeaderLocaleResolver:HTTPリクエストヘッダに含まれるAccept-Languageを使用して、ユーザーのロケールを自動的に判定します。

これらの仕組みを使うことで、ユーザーごとに異なるロケールに対応したメッセージやフォーマットを提供することが可能です。

Spring Bootでの国際化の簡略化

Spring Bootでは、国際化対応がさらに簡単に行えます。application.propertiesファイルでspring.messages.basenameプロパティを設定するだけで、プロパティファイルを自動的に探し、メッセージの切り替えを行うことができます。これにより、国際化対応の実装が大幅に簡略化され、開発者はメッセージの管理に集中できるようになります。

Springの国際化機能は、効率的で柔軟なメッセージ管理を実現し、グローバル対応のアプリケーション開発をサポートします。

メッセージプロパティファイルの作成

Springで国際化対応を実現するためには、各言語ごとにメッセージを定義したプロパティファイルを作成する必要があります。これらのファイルに、アプリケーション内で使用されるテキストやメッセージの翻訳を格納し、ユーザーが選択した言語に応じて動的にメッセージを切り替える仕組みを提供します。

プロパティファイルの命名規則

Springでは、メッセージプロパティファイルは特定の命名規則に従う必要があります。基本的なファイル名に言語コードや国コードを付与することで、複数のロケールに対応するファイルを準備します。

以下が代表的な命名例です:

  • messages.properties:デフォルトのプロパティファイル
  • messages_en.properties:英語用のメッセージファイル
  • messages_fr.properties:フランス語用のメッセージファイル

これにより、ユーザーがリクエストしたロケールに基づいて、適切なファイルからメッセージが読み込まれるようになります。

プロパティファイルの内容例

プロパティファイルには、キーとそれに対応するメッセージを定義します。同じキーを異なる言語ファイルに定義することで、アプリケーションが適切なメッセージを取得できるようになります。

例えば、以下のような内容をそれぞれのプロパティファイルに記述します。

messages.properties(デフォルト言語: 英語)

greeting=Hello
farewell=Goodbye

messages_fr.properties(フランス語)

greeting=Bonjour
farewell=Au revoir

このようにキー(greetingfarewell)を統一しておくことで、同じメッセージを異なる言語で表示できるようになります。

プロパティファイルの配置場所

Springアプリケーションでは、通常、メッセージプロパティファイルをsrc/main/resourcesディレクトリに配置します。このディレクトリにプロパティファイルを置くことで、アプリケーションが自動的にファイルを認識し、メッセージを取得することができます。

プロジェクト構造の例:

src/main/resources/
    messages.properties
    messages_en.properties
    messages_fr.properties

このように各言語のプロパティファイルを配置することで、Springが自動的に言語ごとのメッセージを切り替えることができるようになります。

プロパティファイルにおけるエスケープ文字の使用

特殊文字や改行を含むメッセージを扱う場合、プロパティファイルではエスケープ文字を使用する必要があります。例えば、次のような形式でエスケープを行います:

error.message=This is an error.\nPlease contact support.

\nは改行を表し、メッセージ内で複数行にわたるテキストを表示することが可能です。

以上のように、メッセージプロパティファイルを正しく作成・配置することで、国際化対応が容易に行えるようになります。

メッセージソースの設定方法

Springアプリケーションにおける国際化対応の中心となるのが、MessageSourceの設定です。MessageSourceは、異なるロケール(地域設定)に基づいたメッセージの取得を管理し、メッセージプロパティファイルを利用してアプリケーション内で必要な翻訳を提供します。これにより、ユーザーの言語設定に応じたメッセージを動的に切り替えることが可能になります。

MessageSourceとは

MessageSourceはSpringが提供するインターフェースで、ロケールに応じてメッセージを返す機能を持っています。通常はResourceBundleMessageSourceクラスを使用してプロパティファイルからメッセージを読み込みます。

主な役割は以下の通りです:

  • 指定されたキーに基づいてメッセージを取得
  • ロケールに基づいたメッセージの切り替え
  • デフォルトメッセージの設定

MessageSourceの設定手順

Springでは、MessageSourceをBeanとして定義する必要があります。ResourceBundleMessageSourceを使用してメッセージソースを設定し、プロパティファイルからメッセージを読み込むようにします。

以下のように、Springの設定クラスでMessageSourceをBeanとして定義します。

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;

@Configuration
public class AppConfig {

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}
  • setBasename("messages")では、メッセージプロパティファイルのベース名を指定します。ここで指定するmessagesは、messages.propertiesmessages_en.propertiesといったファイルのベースとなります。
  • setDefaultEncoding("UTF-8")では、メッセージプロパティファイルの文字エンコーディングを指定します。UTF-8を指定することで、日本語や他のマルチバイト文字も問題なく扱えます。

Spring BootでのMessageSource設定

Spring Bootを使用している場合、特に設定クラスを作成しなくても、application.propertiesに必要な設定を追加するだけでMessageSourceを利用できます。以下のようにプロパティを設定します。

spring.messages.basename=messages
spring.messages.encoding=UTF-8
  • spring.messages.basename:メッセージプロパティファイルのベース名
  • spring.messages.encoding:プロパティファイルのエンコーディング

このように設定することで、Spring Bootは自動的にメッセージプロパティファイルを読み込み、ロケールに応じたメッセージを提供します。

メッセージの取得方法

MessageSourceを設定したら、次にメッセージを取得する方法を見ていきましょう。メッセージを取得するには、SpringのMessageSourceを注入し、getMessage()メソッドを使用します。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;

@Controller
public class GreetingController {

    @Autowired
    private MessageSource messageSource;

    @GetMapping("/greet")
    public String greet(Model model, Locale locale) {
        String greetingMessage = messageSource.getMessage("greeting", null, locale);
        model.addAttribute("message", greetingMessage);
        return "greet";
    }
}

この例では、getMessage()メソッドを使用して、greetingというキーに基づくメッセージを指定されたロケール(言語設定)で取得しています。ロケールはコントローラメソッドのパラメータとして渡され、適切な言語に応じたメッセージが返されます。

デフォルトメッセージの設定

MessageSourceを利用する際、指定したキーが見つからない場合に備えて、デフォルトメッセージを設定することも可能です。

String greetingMessage = messageSource.getMessage("greeting", null, "Hello!", locale);

この例では、キーが見つからない場合、デフォルトメッセージとしてHello!が返されます。

このように、MessageSourceの設定によって、アプリケーション内で柔軟なメッセージ管理と国際化対応が実現できます。

Webアプリケーションでの国際化の実装

Springを使用したWebアプリケーションでの国際化対応は、ユーザーが異なるロケールに基づいて動的に言語や文化に適応したインターフェースを表示するために不可欠です。このセクションでは、具体的な国際化の実装方法を説明し、実際のWebアプリケーションでの国際化対応を行うステップを紹介します。

Spring MVCにおける国際化の基本的な流れ

Spring MVCアプリケーションで国際化を実装する基本的な流れは、次のステップで構成されています:

  1. メッセージプロパティファイルを用意し、各言語に対応したメッセージを定義する。
  2. MessageSourceを設定し、プロパティファイルからメッセージを取得できるようにする。
  3. LocaleResolverを設定し、リクエストに基づいてユーザーのロケールを判定する。
  4. ビュー(HTMLテンプレート)でメッセージを表示する。

これらのステップを順番に実装していきます。

1. メッセージプロパティファイルの準備

まず、各言語に対応したメッセージプロパティファイルをsrc/main/resourcesに配置します。以下のようなファイルを作成します。

  • messages.properties:デフォルトの言語(例:英語)
  • messages_fr.properties:フランス語
  • messages_ja.properties:日本語

それぞれのファイルには、キーと翻訳されたメッセージを設定します。

messages.properties(英語)

greeting=Hello
farewell=Goodbye

messages_fr.properties(フランス語)

greeting=Bonjour
farewell=Au revoir

messages_ja.properties(日本語)

greeting=こんにちは
farewell=さようなら

これでアプリケーションが各ロケールに対応したメッセージを取得できるようになります。

2. MessageSourceの設定

次に、MessageSourceを設定してメッセージプロパティファイルから適切なメッセージを取得できるようにします。Spring Bootを使っている場合、application.propertiesで設定します。

spring.messages.basename=messages
spring.messages.encoding=UTF-8

これにより、messages.propertiesファイルをベースにして、アプリケーションが対応するロケールのファイルからメッセージを取得します。

3. LocaleResolverの設定

LocaleResolverは、リクエストに基づいてユーザーのロケールを決定する役割を果たします。Spring MVCでは、LocaleResolverを使用して、ユーザーが使用する言語を決定できます。一般的にはSessionLocaleResolverCookieLocaleResolverを使用します。

以下は、SessionLocaleResolverを用いた設定例です。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

@Configuration
public class LocaleConfig implements WebMvcConfigurer {

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.ENGLISH);
        return localeResolver;
    }
}

ここでは、デフォルトロケールを英語に設定していますが、ユーザーのリクエストに応じて他のロケール(日本語やフランス語など)に切り替えることもできます。

4. ビューでのメッセージ表示

次に、HTMLテンプレートでメッセージを表示する方法を説明します。Springでは、ビューでth:text${}を使用して、メッセージプロパティからメッセージを取得できます。以下はThymeleafを使ったテンプレートの例です。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Internationalization Example</title>
</head>
<body>
    <h1 th:text="#{greeting}">Default Greeting</h1>
    <p th:text="#{farewell}">Default Farewell</p>
</body>
</html>

このテンプレートでは、#{greeting}#{farewell}の部分で、プロパティファイルから取得したメッセージが動的に表示されます。ユーザーが選択した言語に応じて、メッセージが適切な翻訳で表示されます。

動的なロケール切り替え

Springでは、リクエストパラメータを使って動的にロケールを変更することも可能です。以下は、URLパラメータを使って言語を切り替える例です。

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

@Controller
public class LocaleController {

    private final LocaleResolver localeResolver;

    public LocaleController(LocaleResolver localeResolver) {
        this.localeResolver = localeResolver;
    }

    @GetMapping("/change-language")
    public String changeLanguage(@RequestParam("lang") String lang, HttpServletRequest request, HttpServletResponse response) {
        Locale locale = new Locale(lang);
        localeResolver.setLocale(request, response, locale);
        return "redirect:/";
    }
}

このコントローラは、/change-language?lang=frというURLにアクセスすることで、ロケールをフランス語に切り替えることができます。

これにより、Webアプリケーション上でユーザーが動的に言語を切り替えられるようになります。

以上の手順で、Springを使用したWebアプリケーションにおいて、国際化対応を実現することができます。

コントローラでのメッセージ取得

Springでは、国際化対応の一環として、コントローラ内で動的にメッセージを取得し、それをビューや他の処理に渡すことができます。これにより、アプリケーション内でユーザーのロケールに基づいたメッセージやラベルを動的に変更でき、より柔軟な国際化対応が可能になります。

MessageSourceを使ったメッセージの取得

コントローラでメッセージを取得するためには、SpringのMessageSourceを使用します。MessageSourceをコントローラに注入し、getMessage()メソッドを使用してメッセージを動的に取得することができます。

以下に、MessageSourceを使ってメッセージを取得し、それをビューに渡すコントローラの例を示します。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;

@Controller
public class GreetingController {

    @Autowired
    private MessageSource messageSource;

    @GetMapping("/greet")
    public String greet(@RequestParam(name = "lang", required = false) String lang, Model model) {
        Locale locale = (lang != null) ? new Locale(lang) : Locale.getDefault();
        String greetingMessage = messageSource.getMessage("greeting", null, locale);
        model.addAttribute("message", greetingMessage);
        return "greet";
    }
}

コントローラでの処理内容

  1. MessageSourceの注入
    @Autowiredを使ってMessageSourceをコントローラに注入します。これにより、メッセージソースからメッセージを動的に取得できるようになります。
  2. リクエストパラメータによるロケール設定
    クエリパラメータ(ここではlangパラメータ)を使用して、リクエスト時にユーザーのロケール(言語)を受け取ります。パラメータが指定されていない場合は、Locale.getDefault()を使用してデフォルトロケールを適用します。
  3. メッセージの取得
    messageSource.getMessage("greeting", null, locale)を使って、プロパティファイルに定義されたgreetingメッセージを指定されたロケールに基づいて取得します。greetingキーに対応するメッセージは、ユーザーのロケール(例:英語、フランス語、日本語)に基づいて適切な翻訳が選ばれます。
  4. ビューへのメッセージの渡し方
    取得したメッセージをmodel.addAttribute("message", greetingMessage)でビューに渡します。この場合、ビューでmessageという名前の属性を使って、メッセージが表示されます。

例:ビューでのメッセージ表示

以下のThymeleafテンプレートでは、コントローラから渡されたmessage属性を表示します。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Greeting Page</title>
</head>
<body>
    <h1 th:text="${message}">Default Greeting</h1>
</body>
</html>

このテンプレートでは、th:text="${message}"により、コントローラで取得したメッセージが動的に表示されます。例えば、/greet?lang=frのURLをリクエストすると、フランス語のメッセージが表示されます。

動的パラメータの使用

getMessage()メソッドは動的なパラメータを受け取ることもでき、メッセージの中に動的なデータを挿入することが可能です。たとえば、次のようなメッセージがプロパティファイルに定義されている場合:

messages.properties

welcome.message=Welcome, {0}!

これをコントローラで動的に使用する例:

String userName = "John";
String welcomeMessage = messageSource.getMessage("welcome.message", new Object[]{userName}, locale);
model.addAttribute("welcomeMessage", welcomeMessage);

この場合、welcomeMessageには"Welcome, John!"というメッセージが格納され、ビューで表示されます。getMessage()メソッドの第2引数に配列形式でパラメータを渡すことで、メッセージ内のプレースホルダーを動的に置き換えることができます。

例外時のデフォルトメッセージ

もしメッセージキーが見つからなかった場合や、何らかのエラーが発生した場合に備えて、getMessage()メソッドにはデフォルトメッセージを設定することも可能です。

String fallbackMessage = messageSource.getMessage("nonexistent.key", null, "Default Message", locale);

この例では、nonexistent.keyというキーがプロパティファイルに存在しない場合、"Default Message"が返されます。


このように、コントローラでMessageSourceを使ってメッセージを動的に取得し、ユーザーのロケールに基づいて表示を変更することで、柔軟な国際化対応を実現できます。動的なメッセージの表示は、国際化されたアプリケーションの重要な部分を担っており、ユーザーエクスペリエンスの向上に寄与します。

リクエストに基づく言語切替方法

Spring MVCでは、ユーザーのリクエストに基づいて動的に言語(ロケール)を切り替えることが可能です。これにより、ユーザーが選択した言語に応じてアプリケーションの表示内容を変更することができ、グローバルなアプリケーションを構築するための重要な機能となります。

LocaleResolverを使用した言語切替

Springでは、LocaleResolverを使用してユーザーの言語設定(ロケール)を判定し、リクエストに基づいて言語を切り替えることができます。LocaleResolverにはいくつかの実装があり、一般的には次の2つがよく使われます:

  • SessionLocaleResolver:セッション内にロケール情報を保存し、セッションが続く限りそのロケールを適用します。
  • CookieLocaleResolver:クッキーを利用してロケール情報を保存し、ブラウザを閉じた後もロケールが保持されます。

これらを利用して、リクエストごとに言語を切り替えることができます。

SessionLocaleResolverによる設定例

以下は、SessionLocaleResolverを使用してリクエストに基づいて言語を切り替えるための設定例です。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

@Configuration
public class LocaleConfig implements WebMvcConfigurer {

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.ENGLISH);
        return localeResolver;
    }
}

ここでは、デフォルトのロケールを英語に設定していますが、リクエストに応じて言語を動的に切り替えることができます。

HandlerInterceptorを使った動的言語切替

次に、リクエストパラメータで言語を動的に変更する方法を見ていきます。URLに含まれる言語パラメータ(例:?lang=fr)を使って、リクエストごとに言語を変更することができます。この仕組みを実現するには、SpringのHandlerInterceptorを使用します。

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

@Component
public class LocaleChangeInterceptor implements HandlerInterceptor {

    private final LocaleResolver localeResolver;

    public LocaleChangeInterceptor(LocaleResolver localeResolver) {
        this.localeResolver = localeResolver;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String lang = request.getParameter("lang");
        if (lang != null) {
            Locale locale = new Locale(lang);
            localeResolver.setLocale(request, response, locale);
        }
        return true;
    }
}

このインターセプターは、リクエストパラメータlangを確認し、その値に基づいてロケールを変更します。たとえば、?lang=jaといったリクエストがあった場合、ロケールを日本語(ja)に変更します。

LocaleChangeInterceptorの登録

次に、このインターセプターをアプリケーションに登録する必要があります。以下のように、WebMvcConfigurerにインターセプターを追加します。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final LocaleChangeInterceptor localeChangeInterceptor;

    public WebConfig(LocaleChangeInterceptor localeChangeInterceptor) {
        this.localeChangeInterceptor = localeChangeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor);
    }
}

これにより、インターセプターがアプリケーション全体に適用され、リクエストに基づいてロケールが変更されるようになります。

URLでの言語指定

この設定が完了したら、ユーザーはURLパラメータで言語を動的に指定できるようになります。たとえば、以下のURLにアクセスするとアプリケーションの表示言語が日本語に切り替わります。

http://localhost:8080/greet?lang=ja

同様に、フランス語に切り替えるには、次のようなURLを使用します。

http://localhost:8080/greet?lang=fr

このようにして、リクエストごとに異なる言語を指定することで、ユーザーが自由に言語を切り替えることができます。

CookieLocaleResolverによる言語の永続化

さらに、CookieLocaleResolverを使用することで、ロケールをクッキーに保存し、ユーザーが再度アプリケーションを訪れた際にも選択された言語が保持されるように設定することができます。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;

@Configuration
public class LocaleConfig {

    @Bean
    public LocaleResolver localeResolver() {
        CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
        cookieLocaleResolver.setDefaultLocale(Locale.ENGLISH);
        cookieLocaleResolver.setCookieName("lang");
        cookieLocaleResolver.setCookieMaxAge(3600); // 1時間有効
        return cookieLocaleResolver;
    }
}

この設定により、ユーザーの選択した言語がクッキーに保存され、次回以降のアクセスでも選択された言語が維持されます。

まとめ

Spring MVCでのリクエストに基づく言語切替は、LocaleResolverLocaleChangeInterceptorを使用することで簡単に実装できます。リクエストごとに動的にロケールを変更し、SessionLocaleResolverCookieLocaleResolverを使うことで、セッションまたはクッキーにロケールを保持することが可能です。これにより、ユーザーが自由に言語を選択できる柔軟な国際化対応が実現します。

Spring Bootでの国際化対応の設定

Spring Bootを使用することで、国際化(i18n)対応はさらに簡単に実装できます。Spring Bootはデフォルトで多くの機能を自動設定してくれるため、複雑な設定が不要で、国際化に必要なメッセージの管理やロケールの切り替えを簡単に行うことができます。このセクションでは、Spring Bootプロジェクトで国際化対応を設定する具体的な手順について解説します。

1. メッセージプロパティファイルの配置

Spring Bootで国際化を設定する際、まず各言語に対応したメッセージプロパティファイルをsrc/main/resourcesに配置します。Spring Bootは、これらのファイルを自動的に検出し、ユーザーのロケールに応じて適切なメッセージを表示します。

以下のようにメッセージファイルを準備します。

  • messages.properties:デフォルト言語(例:英語)
  • messages_fr.properties:フランス語
  • messages_ja.properties:日本語

それぞれのプロパティファイルには、共通のキーと、それに対応する言語のメッセージを定義します。

messages.properties(英語)

greeting=Hello
farewell=Goodbye

messages_fr.properties(フランス語)

greeting=Bonjour
farewell=Au revoir

messages_ja.properties(日本語)

greeting=こんにちは
farewell=さようなら

これにより、Spring Bootは自動的に言語に応じたメッセージを取得して表示します。

2. application.propertiesでの設定

次に、application.propertiesファイルを使って、メッセージプロパティファイルとエンコーディングの設定を行います。以下の設定を追加します。

spring.messages.basename=messages
spring.messages.encoding=UTF-8
  • spring.messages.basename:メッセージプロパティファイルのベース名を指定します。この設定により、Spring Bootはmessagesファイルをベースに、ロケールに応じたファイルを自動的に探します(例:messages_fr.propertiesmessages_ja.properties)。
  • spring.messages.encoding:プロパティファイルの文字エンコーディングを指定します。UTF-8を使用することで、多言語対応が可能になります。

これで、Spring Bootがメッセージプロパティファイルを正しく読み込み、適切にエンコーディングを扱うことができます。

3. LocaleResolverの設定

Spring Bootでは、LocaleResolverを設定することで、ユーザーのリクエストに基づいて言語を切り替えることができます。LocaleResolverには、SessionLocaleResolverCookieLocaleResolverなどがあり、ここではSessionLocaleResolverを設定する例を紹介します。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;

@Configuration
public class LocaleConfig {

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.ENGLISH); // デフォルトロケールを英語に設定
        return localeResolver;
    }
}

この設定により、セッション内でユーザーのロケールを保持し、リクエストごとにロケールを切り替えることが可能になります。

4. リクエストによる言語切替

LocaleChangeInterceptorを使用して、リクエストパラメータ(例:?lang=fr)によって動的に言語を切り替えることもできます。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang"); // URLパラメータ "lang" で言語を切り替え
        return interceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
}

この設定により、ユーザーがリクエストURLに?lang=frのようなパラメータを付与することで、言語を切り替えることができるようになります。

たとえば、http://localhost:8080/greet?lang=jaのようにリクエストすると、アプリケーションの言語が日本語に切り替わります。

5. ビューでのメッセージ表示

Spring Bootでは、Thymeleafなどのテンプレートエンジンを使用してビューにメッセージを表示できます。メッセージプロパティファイルからメッセージを動的に取得し、ビューに表示する方法を以下に示します。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Internationalization Example</title>
</head>
<body>
    <h1 th:text="#{greeting}">Default Greeting</h1>
    <p th:text="#{farewell}">Default Farewell</p>
</body>
</html>

このテンプレートでは、#{greeting}#{farewell}のプレースホルダを使用して、プロパティファイルからメッセージを取得して表示しています。ロケールが変更されると、自動的に対応する言語のメッセージが表示されます。

6. カスタムメッセージの利用

必要に応じて、コントローラでMessageSourceを使用して、プログラム内で動的にメッセージを取得することもできます。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Locale;

@Controller
public class GreetingController {

    @Autowired
    private MessageSource messageSource;

    @GetMapping("/greet")
    public String greet(Locale locale, Model model) {
        String greetingMessage = messageSource.getMessage("greeting", null, locale);
        model.addAttribute("message", greetingMessage);
        return "greet";
    }
}

このコントローラでは、ユーザーのロケールに応じてgreetingというキーに対応するメッセージを取得し、それをビューに渡しています。

まとめ

Spring Bootを使用すると、国際化対応が非常に簡単になります。application.propertiesファイルで簡単にメッセージソースやエンコーディングを設定でき、LocaleResolverLocaleChangeInterceptorを活用して、ユーザーのリクエストに基づいた言語切替も容易に実装できます。ビューでは、テンプレートエンジンを利用してプロパティファイルからメッセージを表示し、コントローラではMessageSourceを使用してプログラム内で動的にメッセージを扱うことができます。

日付や数値フォーマットの国際化対応

Springフレームワークを使用した国際化対応では、メッセージや言語だけでなく、日付や数値のフォーマットもロケールに応じて正しく表示することが重要です。各国や地域によって日付の表示形式や数値の区切り方が異なるため、これを適切に管理することは、ユーザーエクスペリエンスを向上させる上で欠かせません。

このセクションでは、Springでの国際化対応の一環として、日付や数値フォーマットをロケールに基づいて自動的に切り替える方法について解説します。

1. Springでの日付フォーマット

日付のフォーマットは、地域によって異なります。たとえば、アメリカではMM/dd/yyyy形式が一般的ですが、日本ではyyyy/MM/dd形式が使われます。Springでは、ロケールに応じてこれらのフォーマットを動的に変更することができます。

以下は、Thymeleafテンプレートで日付を表示する例です。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Date Format Example</title>
</head>
<body>
    <p th:text="${#dates.format(localDate, 'yyyy-MM-dd')}">Default Date</p>
</body>
</html>

この例では、#dates.format()を使用して日付を表示しています。ロケールごとに異なる形式を使用する場合、Thymeleafの#dates.format()メソッドにロケール情報を追加することで、ロケールに応じたフォーマットを行うことができます。

たとえば、日本語(ja)ロケールで日付をyyyy/MM/dd形式で表示し、アメリカ英語(en_US)ロケールでMM/dd/yyyy形式に表示させることができます。

2. Springでの数値フォーマット

数値のフォーマットも、地域ごとに異なります。たとえば、アメリカではカンマ区切りで3桁ごとに区切りますが、フランスではスペースで区切るのが一般的です。また、小数点の表示も国によって異なり、アメリカではピリオドを使い、フランスではコンマが使われます。

以下は、Thymeleafで数値をロケールに応じてフォーマットする例です。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Number Format Example</title>
</head>
<body>
    <p th:text="${#numbers.formatDecimal(number, 2, 2, 'COMMA', 'POINT')}">Default Number</p>
</body>
</html>

この例では、#numbers.formatDecimal()を使用して、数値を小数点以下2桁までフォーマットしています。引数を使って、小数点や千の区切り文字の形式を指定することが可能です。ロケールに応じたフォーマットが必要な場合は、Localeオブジェクトを追加してフォーマットを調整できます。

3. Formatterクラスを使用したカスタムフォーマット

Springでは、独自のフォーマットロジックを作成することも可能です。Formatterインターフェースを実装することで、カスタムフォーマッタを作成し、特定のデータ型に対してロケールに基づいたフォーマットを提供することができます。

以下は、カスタムフォーマッタを作成して日付をロケールに基づいてフォーマットする例です。

import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

@Component
public class LocalDateFormatter implements Formatter<LocalDate> {

    @Override
    public LocalDate parse(String text, Locale locale) throws ParseException {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(getPattern(locale));
        return LocalDate.parse(text, formatter);
    }

    @Override
    public String print(LocalDate object, Locale locale) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(getPattern(locale));
        return object.format(formatter);
    }

    private String getPattern(Locale locale) {
        if (locale.equals(Locale.JAPAN)) {
            return "yyyy/MM/dd";
        } else if (locale.equals(Locale.US)) {
            return "MM/dd/yyyy";
        } else {
            return "dd/MM/yyyy"; // デフォルト
        }
    }
}

このフォーマッタは、ロケールに基づいて日付をフォーマットします。日本の場合はyyyy/MM/dd形式、アメリカではMM/dd/yyyy形式、それ以外のロケールではdd/MM/yyyy形式を使用します。

このフォーマッタをSpringに登録するには、以下のようにWebMvcConfigurerに追加します。

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final LocalDateFormatter localDateFormatter;

    public WebConfig(LocalDateFormatter localDateFormatter) {
        this.localDateFormatter = localDateFormatter;
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(localDateFormatter);
    }
}

これにより、アプリケーション全体でロケールに基づいた日付フォーマットが適用されます。

4. application.propertiesでのデフォルトフォーマット設定

application.propertiesで、Springのデフォルトの数値フォーマットや日付フォーマットを設定することも可能です。次のプロパティを設定することで、グローバルなデフォルトフォーマットを定義できます。

spring.mvc.format.date=yyyy-MM-dd
spring.mvc.format.time=HH:mm:ss
spring.mvc.format.datetime=yyyy-MM-dd HH:mm:ss

これにより、アプリケーション内のすべての日付、時刻、日付時刻が指定されたフォーマットで表示されるようになります。

5. ロケールごとのカスタムフォーマット

特定のロケールに対して異なるフォーマットを適用する場合、Localeオブジェクトを使用してロケールを取得し、そのロケールに応じたフォーマットを選択できます。これにより、地域に特有のフォーマットで日付や数値を表示することができます。

たとえば、日本では円記号を使用し、アメリカではドル記号を使った通貨フォーマットを実現できます。SpringのNumberFormatアノテーションを使用することで、簡単に通貨のフォーマットも国際化できます。

import org.springframework.format.annotation.NumberFormat;

public class Product {

    @NumberFormat(style = NumberFormat.Style.CURRENCY)
    private BigDecimal price;

    // ゲッター、セッター
}

このアノテーションを使用することで、ロケールに応じた通貨記号が自動的に表示されます。

まとめ

日付や数値のフォーマットは、国際化対応において重要な要素です。Springを使用すれば、ロケールに基づいた適切なフォーマットを簡単に実装できます。Thymeleafを使ってテンプレート内でフォーマットを動的に変更したり、カスタムフォーマッタを利用して独自のフォーマットロジックを追加することで、グローバルなユーザーに最適な表示形式を提供することが可能です。

国際化対応における注意点

Springで国際化対応を行う際には、いくつかの重要な注意点があります。これらを適切に管理しないと、ユーザーエクスペリエンスを損なう可能性があります。このセクションでは、国際化実装時に避けるべき問題点や、考慮すべきポイントについて解説します。

1. メッセージキーの一貫性を保つ

メッセージプロパティファイルでは、同じキーに異なる言語のメッセージを割り当てます。これにより、コード内で共通のキーを使って言語ごとのメッセージを取得できます。メッセージキーは一貫して使うことが重要であり、ミスや重複を防ぐためにも、意味のあるキー名を付けることが推奨されます。

たとえば、greeting.messageのような意味のあるキーを使用し、特定のメッセージの内容に依存しない名前にすることで、変更が必要になったときに一貫性を保つことができます。

2. プロパティファイルのエンコーディング

メッセージプロパティファイルは、UTF-8エンコーディングで保存する必要があります。UTF-8で保存しないと、マルチバイト文字(日本語や中国語など)が正しく表示されない問題が発生します。特に、多言語対応の際には、全てのプロパティファイルのエンコーディングを統一し、application.propertiesでエンコーディングを明示することが重要です。

spring.messages.encoding=UTF-8

これにより、Springが正しくメッセージを読み込み、表示できるようになります。

3. メッセージのコンテキストを意識する

異なる言語間でのメッセージの意味の違いに注意が必要です。たとえば、英語で一つの単語が複数の意味を持つ場合、他の言語に翻訳するときに、その文脈に応じた適切な翻訳が必要です。このため、翻訳する際には、メッセージのコンテキストをしっかり把握することが大切です。

さらに、文化的な違いを考慮したメッセージの作成も重要です。単に言葉を翻訳するだけでなく、ユーザーの文化に配慮した適切なメッセージを使用する必要があります。

4. 動的パラメータの管理

メッセージに動的な値を埋め込む場合、パラメータの位置やフォーマットが言語によって異なることがあります。MessageSourcegetMessage()メソッドを使用して、パラメータ付きのメッセージを取得する際には、パラメータが適切にフォーマットされるよう注意が必要です。

例えば、次のようにパラメータを使用してメッセージを設定できます:

String welcomeMessage = messageSource.getMessage("welcome.message", new Object[]{"John"}, locale);

プロパティファイルでは、次のようにパラメータを使用します:

welcome.message=Welcome, {0}!

パラメータの位置が異なる言語があるため、翻訳時にフォーマットが崩れないよう注意しましょう。

5. デフォルトメッセージの設定

すべての言語において、全てのメッセージが翻訳されているとは限りません。万が一、対応するメッセージが見つからない場合に備えて、デフォルトメッセージを設定しておくことが重要です。getMessage()メソッドの第4引数としてデフォルトメッセージを指定できます。

String message = messageSource.getMessage("nonexistent.key", null, "Default Message", locale);

これにより、プロパティファイルにキーが存在しない場合でも、適切なデフォルトメッセージが表示されます。

6. 多言語対応のテスト

すべての言語やロケールに対応するメッセージが正しく表示されるかを確認するためには、実際にアプリケーションを複数の言語でテストすることが不可欠です。特に、言語によっては文字数が大きく異なるため、UIのレイアウトが崩れる可能性があります。こうした点を考慮し、テスト時には各言語でのUI表示も確認しましょう。

まとめ

国際化対応を進める上で、メッセージキーの一貫性やエンコーディング、コンテキストの考慮、動的パラメータの管理などに注意することが重要です。特に、すべてのユーザーに対して適切なメッセージが提供されるように、デフォルトメッセージを設定し、全言語での表示をテストすることを怠らないようにしましょう。

まとめ

本記事では、Springフレームワークを使用した国際化対応の実装方法について、基本概念から具体的な設定や実装手順まで詳しく解説しました。メッセージプロパティファイルの作成、MessageSourceLocaleResolverの設定、リクエストに基づく言語切替、日付や数値のフォーマット対応など、国際化の重要なポイントをカバーしました。

国際化対応を正しく実装することで、ユーザーが自身の言語や文化に合わせた快適な体験を得られるようになり、グローバルに対応したアプリケーションを構築できます。これにより、ユーザビリティを向上させ、ビジネスの成長を支援する強力な基盤を作ることができます。

コメント

コメントする

目次
  1. 国際化対応(i18n)の基本概念
    1. なぜ国際化が重要か
    2. ローカリゼーションとの違い
    3. Springにおける国際化対応のメリット
  2. Springにおける国際化対応の仕組み
    1. MessageSourceによるメッセージ管理
    2. LocaleResolverによるロケールの管理
    3. Spring Bootでの国際化の簡略化
  3. メッセージプロパティファイルの作成
    1. プロパティファイルの命名規則
    2. プロパティファイルの内容例
    3. プロパティファイルの配置場所
    4. プロパティファイルにおけるエスケープ文字の使用
  4. メッセージソースの設定方法
    1. MessageSourceとは
    2. MessageSourceの設定手順
    3. Spring BootでのMessageSource設定
    4. メッセージの取得方法
    5. デフォルトメッセージの設定
  5. Webアプリケーションでの国際化の実装
    1. Spring MVCにおける国際化の基本的な流れ
    2. 1. メッセージプロパティファイルの準備
    3. 2. MessageSourceの設定
    4. 3. LocaleResolverの設定
    5. 4. ビューでのメッセージ表示
    6. 動的なロケール切り替え
  6. コントローラでのメッセージ取得
    1. MessageSourceを使ったメッセージの取得
    2. コントローラでの処理内容
    3. 例:ビューでのメッセージ表示
    4. 動的パラメータの使用
    5. 例外時のデフォルトメッセージ
  7. リクエストに基づく言語切替方法
    1. LocaleResolverを使用した言語切替
    2. SessionLocaleResolverによる設定例
    3. HandlerInterceptorを使った動的言語切替
    4. LocaleChangeInterceptorの登録
    5. URLでの言語指定
    6. CookieLocaleResolverによる言語の永続化
    7. まとめ
  8. Spring Bootでの国際化対応の設定
    1. 1. メッセージプロパティファイルの配置
    2. 2. application.propertiesでの設定
    3. 3. LocaleResolverの設定
    4. 4. リクエストによる言語切替
    5. 5. ビューでのメッセージ表示
    6. 6. カスタムメッセージの利用
    7. まとめ
  9. 日付や数値フォーマットの国際化対応
    1. 1. Springでの日付フォーマット
    2. 2. Springでの数値フォーマット
    3. 3. Formatterクラスを使用したカスタムフォーマット
    4. 4. application.propertiesでのデフォルトフォーマット設定
    5. 5. ロケールごとのカスタムフォーマット
    6. まとめ
  10. 国際化対応における注意点
    1. 1. メッセージキーの一貫性を保つ
    2. 2. プロパティファイルのエンコーディング
    3. 3. メッセージのコンテキストを意識する
    4. 4. 動的パラメータの管理
    5. 5. デフォルトメッセージの設定
    6. 6. 多言語対応のテスト
    7. まとめ
  11. まとめ