Thymeleaf + Spring で i18n ~3~

2015.06.11

前回でセッションによって言語情報が保持されるようになりましたが、今回はそれをクッキーで管理するようにしてみました。

  • thymeleaf-i18n
    • デフォルトでは日本語で表示される。
    • リクエストパラメータlangjaが指定されたら日本語、enが指定されたら英語へ切り替わる。
    • 指定言語はクッキーで管理される。
    • クッキーの残存期間は7日間とする。

プロジェクト構成

ビルドツールには引き続きGradleを使っています。

example3
│  build.gradle
│  gradlew
│  gradlew.bat
│  
├─gradle
└─src
    └─main
        ├─java
        │  └─example
        │      └─controller
        │              RootController.java
        │              
        ├─resources
        │  │  logback.xml
        │  │  
        │  └─i18n
        │          Messages_en.properties
        │          Messages_ja.properties
        │          
        └─webapp
            ├─css
            ├─images
            └─WEB-INF
                │  web.xml
                │  
                ├─spring
                │  │  root-context.xml
                │  │  
                │  └─appServlet
                │          servlet-context.xml
                │          
                └─templates
                        index.html

サンプルの確認

Gradle タスクに jetty プラグインを指定してあるので jettyRun タスクの実行でサンプルを確認できます。

$ cd example3
$ ./gradlew jettyRun

デフォルトでは日本語で表示されます。

WS000000

English を選択すると表示が英語になると共に、クッキーにロケール情報が設定されました。

WS000001

設定されたクッキーの情報は下記の通りです。

項目
Name org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE
Value en
Domain localhost
Path /
Expires / Max-Age 2015-06-15T06:06:47.000Z
Size 66
HTTP
Secure
First-Party

クッキーの名称にはデフォルト名org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALEが設定されています。Valueに言語情報が設定されていることと、クッキーが有効な期限Expires / Max-Ageが設定されていることも分かります。

リクエストパラメータを除去して再アクセスしてみます。

WS000003

ちゃんとクッキーに保存された言語で表示されることが確認できます。

WS000004

クッキーを削除してリロードすると……

WS000005

デフォルト言語である日本語に戻りました。

サンプルの説明

Spring の設定

example2 からの変更点は以下の通りです。

CookieLocaleResolver を設定
SessionLocaleResolver を CookieLocaleResolver へ変更します。

example3/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
                           http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-4.1.xsd">


  <!-- **************************************************************** -->
  <!--  RESOURCE FOLDERS CONFIGURATION                                  -->
  <!--  Dispatcher configuration for serving static resources           -->
  <!-- **************************************************************** -->
  <mvc:resources location="/images/" mapping="/images/**" />
  <mvc:resources location="/css/" mapping="/css/**" />


  <!-- **************************************************************** -->
  <!--  SPRING ANNOTATION PROCESSING                                    -->
  <!-- **************************************************************** -->
  <mvc:annotation-driven />
  <context:component-scan base-package="example" />


  <!-- **************************************************************** -->
  <!--  MESSAGE EXTERNALIZATION/INTERNATIONALIZATION                    -->
  <!--  Standard Spring MessageSource implementation                    -->
  <!-- **************************************************************** -->
  <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="i18n/Messages" />
    <property name="defaultEncoding" value="ISO-8859-1" />
  </bean>


  <!-- **************************************************************** -->
  <!--  THYMELEAF-SPECIFIC ARTIFACTS                                    -->
  <!--  TemplateResolver <- TemplateEngine <- ViewResolver              -->
  <!-- **************************************************************** -->

  <bean id="templateResolver"
        class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/templates/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="characterEncoding" value="UTF-8" />
  </bean>

  <bean id="templateEngine"
        class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
  </bean>

  <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
    <property name="characterEncoding" value="UTF-8" />
  </bean>


  <!-- **************************************************************** -->
  <!--  INTERCEPTORS                                                    -->
  <!-- **************************************************************** -->
  <mvc:interceptors>
    <mvc:interceptor>
      <mvc:mapping path="/**"/>
      <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang" />
      </bean>
    </mvc:interceptor>
  </mvc:interceptors>


  <!-- **************************************************************** -->
  <!--  LOCALE RESOLVER                                                 -->
  <!-- **************************************************************** -->
  <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="defaultLocale" value="ja" />
    <property name="cookieMaxAge" value="604800" />
  </bean>


</beans>

CookieLocaleResolver

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="defaultLocale" value="ja" />
    <property name="cookieMaxAge" value="604800" />
  </bean>

localResolverCookieLocaleResolverを設定します。このクラスはorg.springframework.web.util.CookieGeneratorを継承しており、クッキーに指定する様々なプロパティを指定することができます。ここではcookieMaxAgeとしてクッキーの残存期間を7日(単位は秒)として設定しています。

Thymeleaf テンプレート

example2 からの変更はありません。

まとめ

今回は、セッションが切れるとデフォルト言語に戻ってしまう前回のアプリに対する補足のような内容でした。

Thymeleaf と Spring の連携はここで一旦止めて、次回はここまでで用意したプロジェクトをベースによりブランクプロジェクトとして有用な形(DBアクセスやセキュリティ設定などを設定)へ更新していきたいと思います。