Java入門 / Web入門

【Java Web入門 #11】標準タグライブラリ(JSTL)の利用(3)|i18nタグライブラリ

2025.02.21

ここまでの記事では、JSPの標準タグライブラリ(JSTL)のうち、最も基本となるcore タグライブラリ、EL式と組み合わせて関数的に利用することで、細やかな表示の制御を行うことができるfunctionsタグライブラリについて解説しました。

当記事では、サイトの国際化・多言語化に役立つ i18n タグライブラリの利用方法と、同時に利用することの多いJavaアプリケーションのプロパティファイルについて解説します。

◆Java Web入門の過去記事はこちら
◆Java入門 記事一覧はこちら

i18nタグライブラリ

i18n(internationalization)タグライブラリの概要

「i18n」とは「internationalization」(国際化)の略記(数略語)で、「internationalization」先頭(i)と末尾(n)および文字数の18文字から成り立っています。

i18nタグライブラリは、その名の通り国際化と書式化を目的としたタグライブラリです。国によって異なることのある「日付」の表記および「数値」「通貨」を表記するための機能や、言語に応じ動的にメッセージ表示を行うのための機能が準備されています。

taglibディレクティブ

他のJSTLタグと同様、利用のためにJSPに taglib ディレクティブの記述が必要です。i18nタグライブラリのプレフィックスには、通例として「fmt」が利用されます。(当記事でもプレフィックスを「fmt」として説明します)

(JSTL3.0の場合)

Java
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>


(JSTL2.0以前の場合)

Java
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

各タグの仕様

アプリケーション設定

<fmt:setLocale>アプリケーションのロケールを設定する
<fmt:timeZone>アプリケーションのタイムゾーンを設定する
<fmt:setTimeZone>アプリケーションのタイムゾーンを設定する
<fmt:requestEncording>アプリケーションへのリクエストの文字エンコーディングを設定する
参考:Jakarta Standard Tag Library 3.0 Specification Document(公式サイト・英語)
参考:Jakarta Standard Tag Library 3.0 Tagdoc(公式サイト・英語)

<fmt:setLocale>

<fmt:setLocale>タグは、JSPコンテンツのロケールを設定します。タグを記述した以降に、ロケールに依存するコンテンツ(日付・曜日の表記や、数字の桁区切りのフォーマットなど)がある場合は、指定したロケールに従って出力されます。

ロケールを指定した場合は、Webブラウザへのレスポンスも、指定したロケールのコンテンツとして返されます。Webブラウザで「〇〇語のページを翻訳しますか?」といった表示がされるケースでは、この「レスポンスのロケール」で判断されています。

属性名必須説明
value言語コード・国コードを「言語コード_国コード」の書式で設定する。
(例)ja_JP、en_US など
variantバリアントコード(Localeのバリエーションを示すために使用される任意の値)を設定する。
scopeロケール設定のスコープ(有効範囲)を指定する。
(page(デフォルト)/request/session/application のいずれか)
参考:java.util.Locale - Java SE 11 & JDK 11 API Document
参考(wikipedia):ISO 639-1コード一覧(言語コード)、ISO 3166-1(国コード)、IETF言語タグ(バリアントコード)

下記のサンプルでは、ロケールを「ja_JP」(日本語/日本)と「fr_FR」(フランス語/フランス)に設定して、それぞれ日付の表示を行っています。また、最後にロケールを「fr_FR」と指定しているため、Webブラウザがフランス語のコンテンツと判断して翻訳のメッセージが表示されています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<jsp:useBean id="dt" class="java.util.Date"/>

<html>
  <body>
    <%-- ロケールに「ja_JP」を指定 --%>
    <fmt:setLocale value="ja_JP" />  
    <p>    日本語/日本:
      <fmt:formatDate value="${dt}" type="date"  dateStyle="long" />
    </p>

    <%-- ロケールに「fr_FR」を指定 --%>
    <fmt:setLocale value="fr_FR" />  
    <p>フランス語/フランス:
      <fmt:formatDate value="${dt}" type="date"  dateStyle="long" />
    </p>
  </body>
</html>


実行結果:

<fmt:setTimeZone>

<fmt:setTimeZone>タグは、時刻の表示のためのタイムゾーンを設定、または定義します。
コンテンツやアプリケーションに対してタイムゾーンを設定する利用方法と、タイムゾーンのオブジェクトを定義して他のタグで利用できるようにする利用方法があります。

属性名必須説明
value利用するタイムゾーンを指定する。
※設定可能なタイムゾーンIDの一覧はこちらを参照
varタイムゾーンを保持する変数名を指定する。
変数名を指定した場合は、アプリケーションの設定には反映されない。
scopeタイムゾーン設定のスコープ(有効範囲)または変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)

<fmt:setTimeZone>タグは、var 属性(変数名)を指定したかどうかにより、動作が変わる点に注意が必要です。
var 属性を指定しなかった場合は、<fmt:setLocale>タグ同様にタグを記述した以降のコンテンツおよびスコープに対して設定が反映されますが、var 属性を指定した場合は、指定したスコープに変数が保持されるだけで、アプリケーションに設定は反映されません。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<jsp:useBean id="dt" class="java.util.Date"/>
<fmt:setTimeZone value="America/Los_Angeles" var="tz_LosAngels" scope="application"/>

<html>
  <body>
    <p>varを指定したsetTimeZoneの後:
      <fmt:formatDate value="${dt}" type="both" />
    </p>

<fmt:setTimeZone value="America/Los_Angeles"/>

    <p>varを指定しないsetTimeZoneの後:
      <fmt:formatDate value="${dt}" type="both" />
    </p>
  </body>
</html>


実行結果:

<fmt:timeZone>

<fmt:timeZone>タグは、コンテンツ内の時刻表示のためのタイムゾーンを指定します。

属性名必須説明
value利用するタイムゾーンを指定する。
※設定可能なタイムゾーンIDの一覧はこちらを参照

<fmt:setTimezone>タグと異なり、<fmt:timeZone>タグは「ボディ部に内包するコンテンツ」に対してのみ有効となります。

以下のサンプルでは、ハワイの日時を<fmt:setTimezone>タグを利用する方法で、東京の日時を<fmt:timeZone>タグを利用する方法で各々表示しています。

Java
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<jsp:useBean id="dt" class="java.util.Date"/>

<%-- ハワイ標準時のタイムゾーン tz_hawaii を定義 --%>
<fmt:setTimeZone value="Pacific/Honolulu" var="tz_hawaii" />

<html>
  <head>
    <meta charset="UTF-8">
    <title>fmtタグライブラリの利用</title>
  </head>
  <body>
    <%-- fmt:setTimeZoneで定義したタイムゾーンは、timeZone属性に設定する --%>
    <p>ハワイ: 
      <fmt:formatDate value="${dt}" type="both"  timeZone="${tz_hawaii}"/>
    </p>

    <%-- fmt:timeZoneで指定したタイムゾーンは、ボディ部のコンテンツに対し有効 --%>
    <p> 東京: 
      <fmt:timeZone value="Asia/Tokyo">
     	  <fmt:formatDate value="${dt}" type="both" />
      </fmt:timeZone>
    </p>
  </body>
</html>

<fmt:requestEncoding>

<fmt:requestEncoding>タグは、リクエストのエンコードを指定します。

属性名必須説明
valueリクエストのエンコードを指定する。

指定したエンコードは、フォームなどから送信されるパラメーターの文字エンコーディングの判定に利用されます。

Java
<%-- リクエストのエンコードをwindows-31jに指定  --%>
<fmt:requestEncoding value="windows-31j" />

日付オブジェクトの処理

<fmt:formatDate>日付オブジェクトに対してフォーマットを行い文字列を出力する
<fmt:parseDate>日付型の文字列を日付のオブジェクトに変換する
参考:Jakarta Standard Tag Library 3.0 Specification Document(公式サイト・英語)
参考:Jakarta Standard Tag Library 3.0 Tagdoc(公式サイト・英語)

<fmt:formatDate>

<fmt:formatDate>タグは、日付(java.util.Dateクラス)のオブジェクトを、指定に従ってフォーマットした文字列に変換して出力、または変数を定義します。

var 属性を指定しない場合は、タグはJSPコンテンツとして出力されます。指定した場合はフォーマットされた文字列を格納した変数が定義され、コンテンツへの出力は行われません。

属性名必須説明
valueフォーマットする対象の java.util.Date クラスのオブジェクトを指定する。
type表示する項目を、date(日付・デフォルト)、time(時刻)、both(日付+時刻)の何れかを指定する。(大文字/小文字は問わない)
dateStyle日付の表記を fulllongmedium(デフォルト)/short の何れかで指定する。(大文字/小文字は問わない)
timeStyle時刻の表記を fulllongmedium(デフォルト)/short の何れかで指定する。(大文字/小文字は問わない)
pattern日時の表示形式(パターン)を直接指定する。
※パターンに指定できる文字の一覧は、以下のページを参照
 java.text.SimpleDateFormatクラス (日時パターンの一覧を参照)

pattern 属性を指定した場合、type、dateStyle、timeStyle の指定に優先する。
timeZone日時に適用するタイムゾーンのオブジェクトを指定する。
<fmt:timeZone>タグのボディ部にあっても、timeZone属性の指定が優先される。
varフォーマットされた日付文字列を格納する変数名を設定する。
変数名を指定した場合はJSPへの出力は行われない。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
参考:Java 定数フィールド値(java.text.DateFormat) dateStyle/timeStyle


日付および時刻の表記内容を、dateStyle、timeStyle の各属性によって指定することができます。実際に表記される内容はロケールによって決まります。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<jsp:useBean id="dt" class="java.util.Date"/>

<html>
  <body>
    <p>【東京】</p>
    <p>FULL: <fmt:formatDate value="${dt}" type="both" dateStyle="full" timeStyle="full" /></p>
    <p>LONG: <fmt:formatDate value="${dt}" type="both" dateStyle="long" timeStyle="long" /></p>
    <p>MEDIUM: <fmt:formatDate value="${dt}" type="both" dateStyle="medium" timeStyle="medium" /></p>
    <p>SHORT: <fmt:formatDate value="${dt}" type="both" dateStyle="short" timeStyle="short" /></p>
    <hr/>

    <p>【パリ】</p>
    <fmt:setLocale value="fr_FR"/>
    <p>FULL: <fmt:formatDate value="${dt}" type="both" dateStyle="full" timeStyle="full" /></p>
    <p>LONG: <fmt:formatDate value="${dt}" type="both" dateStyle="long" timeStyle="long" /></p>
    <p>MEDIUM: <fmt:formatDate value="${dt}" type="both" dateStyle="medium" timeStyle="medium" /></p>
    <p>SHORT:<fmt:formatDate value="${dt}" type="both" dateStyle="short" timeStyle="short" /></p>
  </body>
</html>


実行結果:


また、pattern 属性を指定した場合は指定した書式が優先され、type、dateStyle、timeStyleの指定に関わらず、pattern 属性で指定したフォーマットで日付・時刻が出力されます。日付や時刻の項目は、1文字で指定した場合は0埋めされずに出力されます。桁数を固定した場合は、yyyy、MMのように出力する桁数で指定します。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<jsp:useBean id="dt" class="java.util.Date"/>

<html>
  <body>
    <p>【東京】</p>
    <p><fmt:formatDate value="${dt}" pattern="G yyyy-MM-dd (E)  KK:mm a z"/></p>
    <p><fmt:formatDate value="${dt}" pattern="G y-M-d (E)  K:m a z"/></p>
    <hr/>

    <p>【パリ】</p>
    <fmt:setLocale value="fr_FR"/>
    <fmt:setTimeZone value="Europe/Paris" />
    <p><fmt:formatDate value="${dt}" pattern="G yyyy-MM-dd (E)  KK:mm a z"/></p>
    <p><fmt:formatDate value="${dt}" pattern="G y-M-d (E)  K:m a z"/></p>
  </body>
</html>


実行結果:

<fmt:parseDate>

<fmt:parseDate>タグは、文字列を日付(java.util.Dateクラス)のオブジェクトに変換します。オブジェクトの格納先(var属性)を指定しなかった場合は、変換されたjava.util.DateクラスのインスタンスのtoStringメソッドの実行結果がJSPに出力されます。

属性名必須説明
value※1日付オブジェクトに変換する文字列を指定する。
type指定した文字列の書式を、date(日付・デフォルト)、time(時刻)、both(日付+時刻)の何れかで指定する。(大文字/小文字は問わない)
timeを指定した場合は、日付は1970/01/01となる。
dateStyle指定した文字列の書式を、fulllongmedium(デフォルト)/short の何れかで指定する。(大文字/小文字は問わない)
timeStyle指定した文字列の書式を、fulllongmedium(デフォルト)/short の何れかで指定する。(大文字/小文字は問わない)
pattern指定した文字列の書式(パターン)を直接指定する。
※パターンに指定できる文字の一覧は、以下のページを参照
 java.text.SimpleDateFormatクラス (日時パターンの一覧を参照)
timeZone日時に適用するタイムゾーンのオブジェクトを指定する。
<fmt:timeZone>タグのボディ部にあっても、timeZone属性の指定が優先される。
parseLocale文字列の変換の際に利用するロケールを指定する。
var変換された日付オブジェクトを格納する変数名を設定する。
変数名を指定した場合はJSPへの出力は行われない。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
※1 valueを指定しない場合は、ボディ部で日付に変換する文字列を指定する(いずれか必須)。両方指定した場合は解析エラーとなる。

文字列を変換する際、文字列の書式を pattern または type、dateStyle、timeStyle の組み合わせと、Locale の指定で正しく設定する必要があります。(指定が誤っていた場合は解析エラーとなります)

また、時刻はtimeStyleの long、full の表記のように(JST など)タイムゾーン名まで指定した場合、またはtimeZone属性を指定した場合は、指定に応じた時刻(現地時刻)として日付オブジェクトが作成されます。

以下のサンプルコード(JSP)では、様々な指定内容で文字列を日付オブジェクトに変換しています。

Java
<%@ page contentType="text/html; charset=UTF-8" import="java.util.Date"%>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
    <%-- 比較用に java.util.Date インスタンスの toString の実行結果を出力 --%>
    <p><%= (new java.util.Date()).toString() %><p>
    <hr/>
    
    <%-- ボディ部で変換する文字列を指定 --%>
    <p><fmt:parseDate>2025/02/19 12:34:56</fmt:parseDate></p>

    <%-- 時刻のみ指定 --%>
    <p><fmt:parseDate value="12:34:56" type="time"/></p>

    <%-- 日付+時刻で指定(デフォルトのロケール・書式) --%>
    <p><fmt:parseDate value="2025/02/19 12:34:56" type="both" /></p>

    <%-- ロケールを指定し、日付+時刻で変換(タイムゾーンはデフォルト) --%>
    <p>
      <fmt:parseDate value="19 févr. 2025, 12:34:56" 
        parseLocale="fr_FR"  type="both" />
    </p>

    <%-- ロケールを指定し、日付+タイムゾーン付き時刻(+timeStyle)で変換 --%>
    <p>
      <fmt:parseDate value="19 février 2025, 12:34:56 CET"
        parseLocale="fr_FR" type="both" dateStyle="long" timeStyle="long"/>
    </p>
  </body>
</html>


実行結果:

数値オブジェクトの処理

<fmt:formatNumber>数値オブジェクトに対し、フォーマットした文字列を出力する
<fmt:parseNumber>数値型の文字列を数値のオブジェクトに変換する
参考:Jakarta Standard Tag Library 3.0 Specification Document(公式サイト・英語)
参考:Jakarta Standard Tag Library 3.0 Tagdoc(公式サイト・英語)

<fmt:formatNumber>

<fmt:formatNumber>タグは、数値型のオブジェクト・文字列を、指定した書式にフォーマットした文字列を出力、または変数に保持します。

フォーマット可能な対象は、数値を表す文字列(”9999”など)、数値型リテラル/ラッパークラス、その他の java.lang.Numberクラス のサブクラス( java.math.BigDecimalクラス など)が対象です。桁区切りや小数点などは、ロケールの設定に従った表記となります。

属性名必須説明
value※2フォーマットする対象の数値型オブジェクト、または文字列を指定する。
type数値のフォーマットとして、number(数値・デフォルト)、currency(通貨)、percent(パーセンテージ)の何れかを指定する。(大文字/小文字は問わない)
pattern数値のフォーマット(パターン)を直接指定する。
※パターンに指定できる文字の一覧は、以下のページを参照
 java.text.DecimalFormatクラス (特殊パターン文字の一覧を参照)

pattern 属性を指定した場合、type、currencyCode、currencySymbol の指定に優先する。
currencyCodeISO 4217に定められた、3文字の通貨コードを指定する。通貨記号の表示位置はロケールの設定に従う。
但し、type が currency 以外の場合は通貨記号は表示されない。
currencySymbol通貨記号(¥、$、£など)を直接指定する。通貨記号の表示位置はロケールの設定に従う。
但し、type が currency 以外の場合は通貨記号は表示されない。また、同時に currencyCode が指定されている場合は currencyCode による既定の通貨記号が優先される。
groupingUsed桁区切りを行うかどうかを、true(行う・デフォルト)、false(行わない)のいずれかで指定する。
maxIntegerDigits整数部分の最大桁数を指定する。超過した部分は前方から削除される。(例・2桁を指定した場合: 123456 → 56)
minIntegerDigits整数部分の最小桁数を指定する。不足している桁は前方にゼロ埋めされる。
(例・6桁を指定した場合: 12 → 000012)
maxFractionDigits小数部分の最大桁数を指定する。超過した部分をRoundした結果となる。※四捨五入ではないことに注意。
(例・1桁を指定した場合: 123.45 → 123.5 / 123.45 → 123.5)
minFractionDigits小数部分の最小桁数を指定する。不足している桁は後方にゼロ埋めされる。
(例・4桁を指定した場合: 123.45 → 123.4500)
varフォーマットされた数値文字列を格納する変数名を設定する。
変数名を指定した場合はJSPへの出力は行われない。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
※2 valueを指定しない場合は、ボディ部で数値型の文字列を指定する(いずれか必須)。両方指定した場合は解析エラーとなる。

以下のサンプルでは、各データ型の数値・文字列を、日本語のデフォルト数値書式(3桁カンマ区切り、小数点はピリオド)でフォーマットしています。

Java
<%@ page contentType="text/html; charset=UTF-8" import="java.math.BigDecimal"%>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<%
  byte b = (byte) 1;
  short s = (short) 22;
  int i = 333;
  long l = 4444l;
  float f = 5555.5f;
  double d = 6666.66d;
  BigDecimal bd = new BigDecimal(7777777);
  String str = "88888888";
  
  pageContext.setAttribute("b", b);
  pageContext.setAttribute("s", s);
  pageContext.setAttribute("i", i);
  pageContext.setAttribute("l", l);
  pageContext.setAttribute("f", f);
  pageContext.setAttribute("d", d);
  pageContext.setAttribute("bd", bd);
  pageContext.setAttribute("str", str);
%>

<html>
  <body>
    <p>byte/Byte:<fmt:formatNumber value="${b}" /></p>
    <p>short/Short:<fmt:formatNumber value="${s}" /></p>
    <p>int/Integer:<fmt:formatNumber value="${i}" /></p>
    <p>long/Long:<fmt:formatNumber value="${l}" /></p>
    <p>float/Float:<fmt:formatNumber value="${f}" /></p>
    <p>double/Double:<fmt:formatNumber value="${d}"/></p>
    <p>BigDecimal:<fmt:formatNumber value="${bd}" /></p>
    <p>String:<fmt:formatNumber value="${str}" /></p>
    <p>value属性:<fmt:formatNumber value="999999999" /></p>
    <p>ボディ部:<fmt:formatNumber>1000000000</fmt:formatNumber></p>
  </body>
</html>


実行結果:


桁区切りや小数点の記号などは、設定したロケールに従ってフォーマットされることに注意してください。以下のサンプルコード(JSP)では、数値/通貨/パーセンテージの各表記について、日本、スペイン、フランスでの表記内容を比較しています。

桁区切りの記号や、通貨記号およびその表記位置が、ロケールの設定により異なっていることがわかります。またロケールを日本とした場合、日本円は補助通貨(ドルに対するセントなど)を持たないため、数値が整数にroundされています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
  <fmt:setLocale value="ja_JP" />
    【日本】<br/>
    数値:<fmt:formatNumber value="1234567.89" type="number" /><br/>
    通貨:<fmt:formatNumber value="1234567.89" type="currency" /><br/>
    パーセンテージ:<fmt:formatNumber value="1.234" type="percent" /><br/>
    <hr/>
  <fmt:setLocale value="es_ES"/>
    【スペイン】<br/>
    数値:<fmt:formatNumber value="1234567.89" type="number" /><br/>
    通貨:<fmt:formatNumber value="1234567.89" type="currency" /><br/>
    パーセンテージ:<fmt:formatNumber value="1.234" type="percent" /><br/>
    <hr/>
  <fmt:setLocale value="fr_FR"/>
    【フランス】<br/>
    数値:<fmt:formatNumber value="1234567.89" type="number" /><br/>
    通貨:<fmt:formatNumber value="1234567.89" type="currency" /><br/>
    パーセンテージ:<fmt:formatNumber value="1.234" type="percent" /><br/>
  </body>
</html>


実行結果:


また既定の書式以外に、pattern 属性で書式を指定することで数値をフォーマットすることも可能です。pattern 属性で指定する書式で利用可能な文字は、java.text.DecimalFormatクラス で利用可能な特殊パターン文字です。

例えば、通貨として表示するが日本円でも小数を表示したい、単価として表示するために前方に「@」を表示したい、といった場合に書式を定義して利用することができます。小数部分の桁数の指定がされていない、または不足している場合は、maxFractionDigitsの指定と同じようにroundされた値が表示されることに注意してください。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
    <%-- 通貨記号を示す特殊文字(¤)を利用する際はロケールの明示が必要 --%>
    <fmt:setLocale value="ja_JP" />

    通貨(小数2桁まで):
      <fmt:formatNumber value="1234567.8" pattern="¤ #,###.00" /><br/>
    単価(小数2桁まで):
      <fmt:formatNumber value="1234.567" pattern="@ #,###.00" /><br/> 
</html>


実行結果:

<fmt:parseNumber>

<fmt:parseNumber>タグは文字列を数値に変換します。数値が整数の場合はLong型、小数やlongの最小値未満または最大値を超える値の場合はDouble型のオブジェクトに変換されます。オブジェクトの格納先(var属性)を指定しなかった場合は、変換後の数値がJSPに出力されます。

属性名必須説明
value※3数値に変換する文字列を指定する。
type指定した文字列の書式を、number(数値・デフォルト)、currency(通貨)、percent(パーセンテージ)の何れかで指定する。(大文字/小文字は問わない)
※currency を指定した場合は、指定した文字列にロケールに適した通貨記号が含まれる必要がある。
※percent を指定した場合は、指定した文字列の末尾に「%」の記述が必要。
pattern指定した文字列の書式(パターン)を直接指定する。
※パターンに指定できる文字の一覧は、以下のページを参照
 java.text.DecimalFormatクラス (特殊パターン文字の一覧を参照)
parseLocale文字列の変換の際に利用するロケールを指定する。
integerOnly整数部のみの数値とするかどうかを、true(整数部のみ)、false(小数部を含む・デフォルト)のいずれかで指定する。
trueを指定した場合、小数部の値は切り捨てられる。
var変換された数値オブジェクトを格納する変数名を設定する。
変数名を指定した場合はJSPへの出力は行われない。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
※3 valueを指定しない場合は、ボディ部で数値に変換する文字列を指定する(いずれか必須)。両方指定した場合は解析エラーとなる。

<fmt:parseNumber>タグで文字列を数値型に変換する場合、変換する文字列がロケールに応じた表記(桁区切り、小数点、通貨単位など)である必要があります。

下記のサンプルコードでは、これらのロケールによって異なる表記の文字列に対して、それに適した書式指定をすることで数値化しています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
  <fmt:setLocale value="ja_JP"/>
    数値[1,234.56]
      <fmt:parseNumber value="1,234.56" /><br/>
    数値[1.234,56](スペイン) → 
      <fmt:parseNumber value="1,234.56" parseLocale="es_ES" /><br/>
    数値[1,234.56](整数部のみ) → 
      <fmt:parseNumber value="1,234.56" integerOnly="true" /><br/>
    通貨[1,234.56]
      <fmt:parseNumber value="¥1,234.56" type="currency" /><br/>
    通貨[$1,234.56](USドル) → 
      <fmt:parseNumber value="$1,234.56" type="currency" parseLocale="en_US" /><br/>
    パーセンテージ[1,234.56%]
      <fmt:parseNumber value="1234.56%" type="percent" />
  </body>
</html>


実行結果:

リソースのメッセージ処理

<fmt:message>.propertiesファイルに設定したリソースのメッセージを出力する
<fmt:setBundle>.propertiesファイルに設定したリソースへのバンドルを生成する
<fmt:bundle>.propertiesファイルに設定したリソースへのバンドルを生成する
参考:Jakarta Standard Tag Library 3.0 Specification Document(公式サイト・英語)
参考:Jakarta Standard Tag Library 3.0 Tagdoc(公式サイト・英語)

プロパティファイルの準備

メッセージ処理を行う準備として、メッセージを定義したプロパティファイル(.propertiesファイル)を、Webアプリケーション内に作成します。
ここでは、Eclipse のエディタを利用して作成、編集する手順をご紹介します。

  • ファイルの作成場所とビルドパス
    まず、プロジェクトの src/main の直下などに、プロパティファイルを格納するフォルダを作成します。(ここでは「resources」フォルダとして作成しました)

    フォルダを作成したら、プロジェクトを右クリックして表示されるメニューから「プロパティ」を表示して、「Javaのビルド・パス」を選択します。
    「Javaのビルド・パス」の画面で一番左の「ソース」タブを選択し、「フォルダーの追加」から作成したフォルダを選択したら、「適用」ボタンをクリックします。
  • プロパティファイルの作成と編集
    次に、プロパティファイルを作成したフォルダの中に作成します。(フォルダ上で右クリック → 新規 → ファイル)。作成するファイルの拡張子は「.properties」としてください。(ここでは「messages.properties」として作成しました)

    プロパティファイルでは、「キー名=値」の書式で1行ずつプロパティを設定します。
    プロパティファイルは日本語などのマルチバイト文字をUnicodeにエスケープする必要がありますが、Eclipseのプラグインであるエディター(Limy プロパティ・エディターなど)で開くことで、日本語のまま作成することが可能です。

    エディターを選択してファイルを開くには、ファイル上で右クリック→「次で開く」から、ファイルを開くエディターを選択します。


  Limy プロパティー・エディターでファイルを編集。
  日本語のままファイルを編集できる。


  プロパティー・ファイル・エディターで確認。
  Unicodeエスケープ形式に変換されている(実際のファイルの内容)。


  ここでは、以下のようにプロパティファイルを作成しました。

msg01=こんにちは。
msg02=今日は良い天気ですね。
  • プロジェクトのビルド
    プロパティファイルを作成、編集したら、プロジェクトのビルドを行います。プロジェクトを右クリックし、メニューから「プロジェクトのビルド」をクリックして(または、プロジェクト上で「Ctrl + b」キーを押して)プロジェクトをビルドします。

    プロジェクトの 「build / classes」フォルダ内に、作成したプロパティファイルがコピーされ、Webアプリケーションの実行時にプロパティファイルが読み込まれるようになります。

リソースバンドルを用いた多言語対応

リソースバンドルを利用して、ロケールの言語コードに応じたメッセージの表示を行うことが可能です。リソースバンドルとは、ロケールごとに固有のオブジェクトを管理するクラスで、リソースバンドルを用いてプロパティファイルにアクセスすることにより、同じキー名のままロケールに応じた値に切り替えることが可能となります。

リソースバンドルを用いた多言語対応を行う場合は、元のプロパティファイルの後ろに「_言語コード」という名前でプロパティファイルを作成します。

・messages.properties (デフォルトのプロパティファイル)

msg01=こんにちは。
msg02=今日は良い天気ですね。

・messages_en.properties (言語コード「en」向けのプロパティファイル)

msg01=Hello.
msg02=It's fine today.

アプリケーションのデフォルトのロケールの場合や、言語コードがついたファイルが見つからない場合は、デフォルトの(言語コードがファイル名についていない)プロパティファイルの内容が参照されます。

<fmt:message>

<fmt:message>タグは、プロパティファイルから取得したメッセージを表示します。
メッセージを表示するためには、<fmt:setBundle>タグ、<fmt:bundle>タグなどを利用して、参照するリソースバンドルを指定する必要があります。

属性名必須説明
key※4表示するメッセージのキー(プロパティファイルで設定したキー)を指定する。
bundle参照するリソースバンドルを指定する。
<fmt:bundle>タグによってリソースバンドルが指定されていても、この設定を優先する。
(後述の<fmt:setBundle>タグ、<fmt:bundle>タグを参照)
var生成されたメッセージ文字列を格納する変数名を設定する。
変数名を指定した場合はJSPへの出力は行われない。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
※4 keyを指定しない場合は、ボディ部でメッセージのキーを指定する(いずれか必須)。但しこの場合、<fmt:param>タグを利用した置換パラメーターへの差し込みはできない。key属性とボディ部に両方キーを指定した場合は、key属性の指定が優先される。

<fmt:setBundle> + <fmt:message>

<fmt:setBundle>タグを用いて、ロケールに応じたリソースバンドルを取得することができます。

属性名必須説明
basename取得するリソースバンドルの名前を指定する。
(プロパティファイルの「_言語コード」と拡張子の部分を除いたファイル名)
var取得したリソースバンドルを格納する変数名を設定する。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)

以下のサンプルコードでは<fmt:message>タグの中で、取得したリソースバンドルを指定してプロパティファイルに定義されたメッセージを表示しています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
    <%-- リソースバンドルを取得(messages.properties--%>
  	<fmt:setBundle basename="messages" var="rsc" />

    <%-- メッセージを出力 --%>
    <p>
      msg01: <fmt:message bundle="${rsc}" key="msg01" />
    </p>
    <p>
      msg02: <fmt:message bundle="${rsc}" key="msg02" />
    </p>
  </body>
</html>


(messages.properties)

msg01=こんにちは。
msg02=今日は良い天気ですね。

実行結果:

<fmt:bundle> + <fmt:message>

<fmt:bundle>タグを用いることでも、ロケールに応じたリソースバンドルを取得することができます。

属性名必須説明
basename取得するリソースバンドルの名前を指定する。
(プロパティファイルの「_言語コード」と拡張子の部分を除いたファイル名)
prefixメッセージを取得するキーのプレフィックスを指定する。
例えばキーが「sample.msg01」「sample.msg02」であった場合、prefixに「sample.msg」と指定することで、ボディ部に配置した<fmt:message>タグではkey属性を「01」「02」とだけ指定してリソースにアクセスできる。

<fmt:setBundle>タグでは取得したリソースバンドルを変数に格納していたのに対し、<fmt:bundle>タグではボディ部に記述したコンテンツに対して取得したリソースバンドルを適用します。

以下のサンプルコードでは、<fmt:bundle>タグと<fmt:message>タグを利用してプロパティファイルから取得したメッセージを出力しています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
    <%-- リソースバンドルを取得(messages.properties--%>
    <fmt:bundle  basename="messages">
      <%-- <fmt:bundle>タグのボディ部でメッセージを出力 --%>
      <p>
        msg01: <fmt:message key="msg01" />
      </p>
      <p>
        msg02: <fmt:message key="msg02" />
      </p>
    </fmt:bundle>
  </body>
</html>


(messages.properties)

msg01=こんにちは。
msg02=今日は良い天気ですね。

実行結果:

<fmt:param>

<fmt:param>タグを利用して、プロパティファイルから取得したメッセージに対して差し込む文言を設定します。<fmt:param>タグは、差し込み対象メッセージの<fmt:message>タグのボディ部に記述します。

属性名必須説明
value※5メッセージに差し込む文字列を指定する。
※5 valueを指定しない場合は、ボディ部で差し込む文字列を指定する(いずれか必須)。両方指定した場合は解析エラーとなる。

<fmt:param>タグで指定した文字列を差し込むには、プロパティファイルに定義するメッセージ内に{0}{1}{2}・・・の書式で、0から順に置換文字列を指定します。

1つの<fmt:message>タグに対し、ボディ部での<fmt:param>タグの設定順に{0}{1}{2}・・・に対する差し込み文字列を指定します。

メッセージに設定した置換文字列に対し<fmt:param>タグの数が不足している場合、置換文字列はそのまま出力されます。<fmt:param>タグのほうが多い場合は、超過した分は無視されます。また、メッセージに同じ置換文字列({0}と{0} など)が複数回設定されている場合は、1つの差し込み文字列で当該箇所が全て置換されます。

(messages.properties)

msg01=こんにちは。
msg02=今日は良い天気ですね。
msg03=こんにちは、{0}さん。
msg04={0}は、{1}ではありません。

msg05={0}とは違うのだよ、{0}とは!

※プロパティファイルを変更した場合、反映のためにはWebアプリケーションの再ビルドと再起動が必要です。再ビルドおよび再起動を行っても反映されない場合、対象のサーバーを右クリック→「クリーン」を選択して、キャッシュのクリアを行って下さい。


以下のサンプルコードでは<fmt:param>タグを利用して、プロパティファイルから取得したメッセージの文字列に差し込みを行っています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>
<c:set var="userName" value="knovus" />
<html>
  <body>
  	<fmt:setBundle basename="messages" var="rsc" />

    <p>
      msg03: 
      <fmt:message bundle="${rsc}" key="msg03" >
        <%-- メッセージに埋め込む文言を設定 --%>
        <fmt:param value="${userName}" />
      </fmt:message>
    </p>
    <p>
      msg04: 
      <fmt:message bundle="${rsc}" key="msg04" >
        <fmt:param value="りんご" />
        <fmt:param value="野菜" />
      </fmt:message>
    </p>
  </body>
</html>


実行結果:

ロケールの変更とリソースバンドルの切り替え

多言語用のプロパティファイルを作成した場合、JSP上でロケールを指定することで、言語コードに応じて取得されるリソースバンドルが切り替わります。

以下のサンプルコードでは、同じ内容の<fmt:message>タグを記述していますが、ロケールの設定に応じて、デフォルト(日本語)と英語のメッセージが切り替えられて表示されています。

Java
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.fmt" prefix="fmt" %>
<html>
  <body>
    <%-- デフォルトのロケールのリソースバンドルを取得 --%>
  	<fmt:setBundle basename="messages" var="rsc" />

    <%-- メッセージを出力 --%>
    <p>
      msg01: <fmt:message bundle="${rsc}" key="msg01" />
    </p>
    <p>
      msg02: <fmt:message bundle="${rsc}" key="msg02" />
    </p>
    
    <hr/>
    
    <%-- ロケールを「en_US」切り替えてリソースバンドルを再取得 --%>
    <fmt:setLocale value="en_US" />
    <fmt:setBundle basename="messages" var="rsc" />
    
    <%-- 上記と同じタグの内容でメッセージを出力 --%>
    <p>
      msg01: <fmt:message bundle="${rsc}" key="msg01" />
    </p>
    <p>
      msg02: <fmt:message bundle="${rsc}" key="msg02" />
    </p>    
  </body>
</html>


実行結果:


<fmt:setBundle>タグの場合、取得する時点のロケール設定に応じたリソースバンドルが取得されます。<fmt:bundle>タグでリソースバンドルを指定する場合も、<fmt:bundle>タグのボディ部でロケールを切り替えることはできません。ロケールを切り替えるには、<fmt:setBundle>タグや<fmt:bundle>タグの実行前に指定する必要があります。

Java
<%-- リソースバンドルを取得する前にロケールを指定 --%>
<fmt:setLocale value="en_US" />

<fmt:bundle basename="messages">
<p>
  msg01: <fmt:message key="msg01" />
</p>
<p>
  msg02: <fmt:message key="msg02" />
</p>
</fmt:bundle>



今回の記事では i18n タグライブラリの機能をご紹介しました。フォーマット機能を活用したり、リソースバンドルを併用することで、同一のJSPコンテンツから多言語対応のWebページを作成することが可能です。

近年のWeb開発ではJSTLの利用機会は以前より減っているかもしれませんが、国際化対応をはじめとしたWebアプリケーション開発の基礎となる概念を学ぶことができると思います。

次回の記事では、JSTLのXMLタグライブラリについて解説します。

株式会社GSI 採用サイト

新しいこと、始めよう

あなたとともに歩を進めるWEBメディア

広告

広告