概要
Springのメッセージ管理を行うMessageSourceを使用して外部ファイルからメッセージを取得する方法についてまとめた。
MessageSourceはプロパティファイルに定義したメッセージを取得する機能を提供する。
また、SpringのBeanバリデーション等にあわせて自動でバリデーションエラーメッセージを取得する機能も提供する。
前提
Mavenプロジェクトの作成方法と基本的な画面疎通については以下を参照。
概要 Spring MVCフレームワークを使用して開発を進める際、Mavenプロジェクトの基本的なセットアップ方法についてまとめた。 前提 プロジェクトの具体的な作成方法については以下に記載。 [siteca[…]
概要 Springを学びなおすにあたり、Spring MVCでHello Worldしたのでその基本的な方法についてまとめた。 前回はBean定義ファイルをJavaのアノテーションベースで作成したが、今回はXMLベースで作成する。 […]
ファイル詳細
今回修正または新規作成するファイルは以下となる。
※主要ファイルのみ表示
ファイル詳細
prototype
│
└─src
└─main
├─java
│ └─com
│ └─example
│ └─prototype
│ ├─biz
│ │ └─util
│ │ └─PropertyUtils.java⇒メッセージを取得するユーティリティクラス
│ │
│ └─web
│ └─controller
│ │
│ └─WelcomeController.java⇒メッセージを取得してクライアントに渡す
│
├─resources
│ │
│ └─META-INF
│ ├─messages_ja.properties⇒メッセージ内容を定義
│ │
│ └─spring
│ └─applicationContext.xml⇒MessageSourceをBean定義
│
└─webapp
└─WEB-INF
│
└─views
│
└─top.jsp⇒メッセージの表示
事前準備
メッセージのプロパティファイルを用意する。
JavaプロパティファイルはデフォルトでISO-8859-1エンコーディングを使用するように設計されている。
そのため、ファイルを作成したら文字コードは「ISO-8859-1」に変更する。
messages_ja.properties
######################################
# メッセージ
######################################
welcome.msg=ようこそ!
greeting.msg=こんにちは、{0}さん
MessageSource
MessageSourceには主要な実装クラスが2つある。
・ReloadableResourceBundleMessageSource
上記のどちらかをDIコンテナに登録して使用していく。
それぞれの特徴に合わせて利用する。
ResourceBundleMessageSource
ResourceBundleMessageSourceの特徴は以下となる。
・プロパティファイルの変更を反映させるには、アプリケーションを再起動する必要あり
・パフォーマンスが比較的高い
ReloadableResourceBundleMessageSource
ReloadableResourceBundleMessageSourceの特徴は以下となる。
・プロパティファイルのリロード間隔は設定可能
・上記故にアプリケーションの再起動なしにプロパティファイルの更新を反映させることができる
MessageSourceの利用
ResourceBundleMessageSourceまたはReloadableResourceBundleMessageSourceを利用してメッセージを取得する方法について紹介する。
Bean定義
MessageSourceをDIコンテナに登録する。
ResourceBundleMessageSourceまたはReloadableResourceBundleMessageSourceでBean定義時のプロパティファイルの指定方法が異なるので注意する。
ResourceBundleMessageSource
ResourceBundleMessageSourceのBean定義の場合。
applicationContext.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- メッセージ管理 -->
<!-- ResourceBundleMessageSourceを使用する場合 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="META-INF/messages" />
</bean>
</beans>
ReloadableResourceBundleMessageSource
ReloadableResourceBundleMessageSourceのBean定義の場合。
applicationContext.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- メッセージ管理 -->
<!-- ReloadableResourceBundleMessageSourceを使用する場合 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames"
value="classpath:META-INF/messages" />
<property name="cacheSeconds" value="3600" /><!-- 1時間ごとにリロード -->
</bean>
</beans>
メッセージユーティリティ
MessageSourceをDIコンテナから取得してそのまま使用することでもできるが、もっとシンプルに利用するためMessageSourceをラップしてユーティリティクラスを作成する。
ユーティリティクラスの作成
プロパティのメッセージキーを指定してメッセージ内容を取得するユーティリティクラスを作成する。
※国際化については当記事では扱わない
PropertyUtils.java
package com.example.prototype.biz.util;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;
@Component // ①
public class PropertyUtils {
@Autowired // ②
private MessageSource messageSource;
// メッセージの取得
public String getMessage(String key) { // ③
return getMessage(key, null);
}
// メッセージの取得
public String getMessage(String key, Object[] args) {
return messageSource.getMessage(key, args, Locale.JAPANESE);
}
}
private MessageSource messageSource;
DIコンテナからMessageSourceインスタンスを取得する。
プロパティのメッセージキーを指定してメッセージ内容を取得する。
コンポーネントスキャンの設定
作成したユーティリティクラスをDIコンテナに登録するため、コンポーネントスキャンの設定を行う。
applicationContext.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- メッセージ管理 -->
(略)
<!-- コンポーネントスキャン -->
<context:component-scan
base-package="com.example.prototype.biz" />
</beans>
ユーティリティクラスを含むパッケージをコンポーネントスキャンの対象としている。
メッセージの利用
メッセージを利用する準備は整ったので、プロパティからメッセージを取得する。
コントローラーからメッセージ情報を取得して画面に表示する方法、画面側から直接メッセージプロパティを参照する方法を紹介する。
コントローラー
ユーティリティクラスのインスタンスを取得してメッセージを取得する。
WelcomeController.java
package com.example.prototype.web.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.prototype.biz.util.PropertyUtils;
@Controller
public class WelcomeController {
@Autowired // ①
private PropertyUtils propertyUtils;
@GetMapping(value = "/")
public String top(Model model) {
model.addAttribute("welcomeMsg", propertyUtils.getMessage("welcome.msg")); // ②
model.addAttribute("user", "山田");
return "top";
}
}
private PropertyUtils propertyUtils;
ユーティリティクラスのインスタンスを取得する。
メッセージプロパティに定義しているメッセージキーを指定してメッセージ内容を取得している。
取得したメッセージを”welcomeMsg”というキーでクライアント側に渡している。
画面側
サーバー側から渡されたメッセージ内容の表示と、直接メッセージプロパティを参照する方法を紹介する。
top.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<%@ include file="/WEB-INF/common/header_common.jsp"%>
</head>
<body>
<div class="container mt-5">
<h2 class="text-center">Hello World</h2>
<p>${welcomeMsg }</p>
<p>
<fmt:message key="greeting.msg">
<fmt:param value="${user }" />
</fmt:message>
</p>
<ul>
<li><a href='<c:url value="/hoge/"/>'>リクエスト方法の確認</a></li>
</ul>
</div>
</body>
</html>
上記はコントローラーにてModelオブジェクトに格納したメッセージを表示している。
上記はJSTLを使用して直接”greeting.msg”を参照している。
上記はコントローラーにてModelオブジェクトに格納した値を表示している。
ブラウザ
ブラウザ上では最終的に以下のように表示される。