ロケール

Spring のアーキテクチャのほとんどの部分は、Spring Web MVC フレームワークがサポートするように、国際化をサポートしています。DispatcherServlet では、クライアントのロケールを使用してメッセージを自動的に解決できます。これは、LocaleResolver オブジェクトを使用して行われます。

リクエストが受信すると、DispatcherServlet はロケールリゾルバーを探し、見つかった場合はそれを使用してロケールを設定しようとします。RequestContext.getLocale() メソッドを使用すると、ロケールリゾルバーによって解決されたロケールを常に取得できます。

自動ロケール解決に加えて、インターセプターをハンドラーマッピングにアタッチして(ハンドラーマッピングインターセプターの詳細についてはインターセプトを参照)、特定の状況(たとえば、リクエストのパラメーターに基づいて)でロケールを変更することもできます。

ロケールリゾルバーとインターセプターは org.springframework.web.servlet.i18n パッケージで定義され、通常の方法でアプリケーションコンテキストで構成されます。以下のロケールリゾルバーの選択が Spring に含まれています。

タイムゾーン

クライアントのロケールを取得することに加えて、多くの場合、タイムゾーンを知ることは有用です。LocaleContextResolver インターフェースは LocaleResolver の拡張機能を提供します。これにより、リゾルバーはより豊富な LocaleContext を提供でき、タイムゾーン情報を含めることができます。

利用可能な場合、RequestContext.getTimeZone() メソッドを使用してユーザーの TimeZone を取得できます。タイムゾーン情報は、Spring の ConversionService に登録されている日付 / 時刻 Converter および Formatter オブジェクトによって自動的に使用されます。

ヘッダーリゾルバー

このロケールリゾルバーは、クライアント(Web ブラウザーなど)によって送信されたリクエスト内の accept-language ヘッダーをインスペクションします。通常、このヘッダーフィールドには、クライアントのオペレーティングシステムのロケールが含まれています。このリゾルバーはタイムゾーン情報をサポートしていないことに注意してください。

このロケールリゾルバーは、クライアント上に存在する可能性のある Cookie をインスペクションし、Locale または TimeZone が指定されているかどうかを確認します。指定されている場合は、指定された詳細情報を使用します。このロケールリゾルバーのプロパティを使用することで、Cookie の名前と最大有効期間を指定できます。次の例では、CookieLocaleResolver Bean を定義しています。

  • Java

  • Kotlin

  • XML

@Configuration
public class WebConfiguration {

	@Bean
	public LocaleResolver localeResolver() {
		CookieLocaleResolver localeResolver = new CookieLocaleResolver("clientlanguage");
		localeResolver.setCookieMaxAge(Duration.ofSeconds(100000));
		return localeResolver;
	}
}
@Configuration
class WebConfiguration {

	@Bean
	fun localeResolver(): LocaleResolver = CookieLocaleResolver("clientlanguage").apply {
		setCookieMaxAge(Duration.ofSeconds(100000))
	}
}
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">

	<constructor-arg index="0" value="clientlanguage"/>

	<!-- in seconds. If set to -1, the cookie is not persisted (deleted when browser shuts down) -->
	<property name="cookieMaxAge" value="100000"/>

</bean>

セッションリゾルバー

SessionLocaleResolver を使用すると、ユーザーのリクエストに関連付けられている可能性のあるセッションから Locale および TimeZone を取得できます。CookieLocaleResolver とは対照的に、この戦略はローカルで選択されたロケール設定をサーブレットコンテナーの HttpSession に保存します。結果として、これらの設定はセッションごとに一時的であるため、各セッションが終了すると失われます。

Spring Session プロジェクトなどの外部セッション管理メカニズムと直接的な関連はないことに注意してください。この SessionLocaleResolver は、現在の HttpServletRequest に対して対応する HttpSession 属性を評価および変更します。

ロケールインターセプター

HandlerMapping 定義の 1 つに LocaleChangeInterceptor を追加することで、ロケールの変更を有効にすることができます。リクエスト内のパラメーターを検出し、それに応じてロケールを変更します。ディスパッチャーのアプリケーションコンテキストで、LocaleResolver の setLocale メソッドが呼び出されます。次の例は、siteLanguage というパラメーターを含むすべての *.view リソースの呼び出しでロケールが変更されることを示しています。たとえば、URL domain.com/home.view?siteLanguage=nl (英語)  へのリクエストでは、サイトの言語がオランダ語に変更されます。次の例は、ロケールをインターセプトする方法を示しています。

  • Java

  • Kotlin

  • XML

@Configuration
public class WebConfiguration {

	@Bean
	public LocaleResolver localeResolver() {
		return new CookieLocaleResolver();
	}

	@Bean
	public SimpleUrlHandlerMapping urlMapping() {
		SimpleUrlHandlerMapping urlHandlerMapping = new SimpleUrlHandlerMapping();
		LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
		interceptor.setParamName("siteLanguage");
		urlHandlerMapping.setInterceptors(interceptor);
		urlHandlerMapping.setUrlMap(Map.of("/**/*.view", "someController"));
		return urlHandlerMapping;
	}
}
@Configuration
class WebConfiguration {

	@Bean
	fun localeResolver(): LocaleResolver {
		return CookieLocaleResolver()
	}

	@Bean
	fun urlMapping() = SimpleUrlHandlerMapping().apply {
		setInterceptors(LocaleChangeInterceptor().apply {
			paramName = "siteLanguage"
		})
		urlMap = mapOf("/**/*.view" to "someController")
	}
}
<bean id="localeChangeInterceptor"
	  class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
	<property name="paramName" value="siteLanguage"/>
</bean>

<bean id="localeResolver"
	  class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>

<bean id="urlMapping"
	  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="interceptors">
		<list>
			<ref bean="localeChangeInterceptor"/>
		</list>
	</property>
	<property name="mappings">
		<value>/**/*.view=someController</value>
	</property>
</bean>