<fmt:message>
SYNOPSIS
| key="キー名" |
| bundle="変数名" |
| var="変数名" |
| scope="page|request|session|application" |
| <fmt:param> * | - | メッセージのフォーマットに使用するパラメータです. |
| key 属性が省略された場合のキー名を記述します. | ||
説 明
適切なロケールのリソースバンドルからメッセージを参照して出力します。
<fmt:param> タグを使用することで
MessageFormat
形式のフォーマットを行うことができます。
適切なリソースバンドルが選択されていない場合や、key 属性に
対応するリソースが存在しない場合、文字列 "???key???"
が出力されます (??? が Java の文字化けと紛らわしいので注意してください)。
[注意] この機能は <c:out>
と違い出力文字を XML エスケープしません。リソース定義自体は
システムで静的であるため、問題があるなら作成時にエスケープしておけば
良いのですが、ユーザの入力値やデータベースから取得する値などをパラ
メータとして埋め込んで使用する場合は十分に注意する必要があります。
この危険性については
クロスサイトスクリプティング
(Cross Site Scripting, CSS, XSS)
やスクリプトインジェクション (Script Injection) で検索してください。
属 性
リソースバンドルから参照するこのメッセージのキーです。 省略した場合はこのタグ内の評価結果をキーとして使用します。
このタグが <fmt:bundle> で囲まれている場合、その prefix
属性が指定されているならその接頭辞を省略して記述することができます。
値が null もしくは長さ 0 の文字列の場合、キーに対するリソースが見つからなかった
ものとして動作します (この時出力されるメッセージは ?????? です)。
メッセージを参照するリソースバンドルを指定します。
これは <fmt:setBundle> の var 属性で指定した名前を EL で記述します。
この属性を省略した場合は設定変数 javax.servlet.jsp.jstl.fmt.localizationContext
に設定されているのリソースバンドルを使用します。これはこのタグを囲っている
<fmt:bundle> や、var 属性を省略した <fmt:setBundle>
のリソースバンドルを意味します。
タグが <fmt:bundle> に囲まれていない状態でこの属性を省略したり、
bundle で指定したリソースバンドルが存在しない場合、出力は
???key??? となります。
取得 (またはフォーマット) したメッセージ文字列を格納する変数名を指定します。
この属性を指定した場合、このタグの位置でメッセージの出力は行われません。
scope 属性を指定した場合は必須です。
内 容
使用例
リソースバンドルの使用
<fmt:bundle> のサンプルで使用した
リソースバンドルをここでも使用します。日本語版リソースバンドルは以下の通りです
(native2ascii で変換を行う前)。
food.japanese.susi.tuna = まぐろ food.japanese.susi.fattytuna = トロ food.japanese.susi.abalone = あわび food.japanese.susi.turbot = ひらめ food.japanese.susi.congereel = あなご food.japanese.susi.flatfish = かれい food.japanese.susi.seaurchin = うに food.japanese.susi.calamari = いか food.japanese.susi.herringroe = 数の子 food.japanese.susi.octopus = たこ
??? が付加されているのが分かります。
<fmt:bundle basename="biz.moyo.lab.resource.sample.gourmet"> <fmt:message key="food.japanese.susi.turbot" /><br> <fmt:message key="food.japanese.susi.bonito" /><br> <fmt:message key="" /><br> </fmt:bundle>
ひらめ ???food.japanese.susi.bonito??? ??????
フォーマットパラメータの使用
MessageFormatmessage.greeting = hello world, {0} {1}
<c:set var="userName" value="moyo" /> <fmt:setBundle basename="biz.moyo.lab.resource.sample.message" /> <fmt:message key="message.greeting"> <fmt:param>Mr.</fmt:param> <fmt:param><c:out value="${userName}" /></fmt:param> </fmt:message>
hello world, Mr. moyo
<fmt:setBundle basename="biz.moyo.lab.resource.sample.message" /> <fmt:param>Mr.</fmt:param> <fmt:message key="message.greeting" />
hello world, Mr. {1}
クロスサイトスクリプティング
<fmt:message> タグを使った出力は XML エスケープされないため、
プロパティファイル上で記述した HTML 書式はそのままブラウザに反映されます。
しかしパラメータを埋め込むときは注意が必要です。例えば以下は任意のエラー
メッセージを出力するフォーマットですが:
errormessage = [<b>ERROR</b>] 入力値不正:{0}
<c:set var="userinput" value="<script>alert(document.cookie);</script>" />
<fmt:message key="errormessage">
<fmt:param value="${userinput}" />
</fmt:message>
[<b>ERROR</b>] 入力値不正:<script>alert(document.cookie);</script>
[ERROR] 入力値不正:
自分で自分のブラウザ上のスクリプトを動かす分にはあまり問題もありません。
何が起きても困るのは自分です。しかし、もしこれがチャットや掲示板で行われ、
不特定多数のブラウザで任意のスクリプトが動かせるとしたら大変危険です。