2007 年 4 月 20 日 23 時 5 分

一覧画面にメッセージリソースを使う


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


[写真]


<message-resources> で登録したメッセージリソースは、
Bean タグライブラリの <bean:message> で取り出して使う。

メッセージリソースのキーを指定する方法は 2 つある。
1 つは、key 属性を使って直接キー文字列を指定する方法、
もう 1 つは、name 属性や property 属性を使って、
スコープ属性に登録してある Bean 値を読み取り、
その値をキーとして間接的に使う方法である。

list.jsp の既定の処理の値は、
リクエスト属性「filter」に登録されている Bean の、
「info.defaultAction」プロパティから取得でき、
その値は、「allow」か「deny」である。

もし name 属性と property 属性を使うとすれば、
「allow」か「deny」というキーを探してしまうので駄目だ。

今回は、値が「allow」ならキー「value.action.allow」を、
値が「deny」ならキー「value.action.deny」を使って、
メッセージリソースから値を取り出したいので、
key 属性と EL 式を使って以下のように書くことにする。

key="value.action.${filter.info.defaultAction}"

${filter.info.defaultAction} は EL 式であり、
どこかのスコープの「filter」属性の Bean の、
「info.defaultAction」プロパティの値に置換される。
その結果、key 属性の値は、
「value.action.allow」か「value.action.deny」となり、
目的とするキーの名前に一致する。

では、list.jsp を書き換えてみよう。

========== /WEB-INF/pages/filter/list.jsp ==========
(…前略…)

    <h1>パケットフィルタ</h1>
    <html:form action="/filter/edit-info">
        <p>
            既定の処理:
            <bean:message
                    key="value.action.${filter.info.defaultAction}" />
            <br />
            備考:
            <bean:write name="filter"
                    property="info.note" />
        </p>
        <p>
            <html:submit>編集</html:submit>
        </p>
    </html:form>
(…後略…)
========== end of /WEB-INF/pages/filter/list.jsp ==========

さて、あと一つ仕事がある。

国際化を行うならば、「既定のロケール」が邪魔になる。

ResourceBundle や MessageResources が、
ロケールに基づいて解決する順序は以下の通り。

1. 指定したロケールに完全一致するリソース
2. 指定したロケールの言語と国が一致するリソース
3. 指定したロケールの言語が一致するリソース
4. 既定のロケールに対応するリソース
5. ロケール非依存の基底リソース

問題となるのは 4 と 5 である。
ロケール非依存のリソースよりも、
既定のロケールのリソースの優先順位が高いことだ。

今回のように既定の言語として、英語を使い、
その他の言語にローカライズするような場合、
英語のリソースはロケール非依存のリソースに格納し、
英語用の *_en.properties 等を作成しないことが多い。

この狙いは、必要な言語だけリソースでローカライズして、
非対応の言語でもとりあえず英語で表示できるということだ。

しかし、この状況でもし既定のロケールが ja_JP であり、
もし ja_JP のリソースを用意していれば、
上記の狙いはうまくいかなくなる。

例えば、ブラウザのリクエストが en_US 等の場合、
上記優先順位に従って *_en_US => *_en と探された後、
何と *_ja_JP に移ってしまうからである。

ロケール非依存のリソースを安全に読み込ませるためには、
既定のロケールをなしにしておくのが好ましいのだ。

もし Java VM にコマンドラインパラメータを渡せるなら、
「-Duser.language= -Duser.region= -Duser.variant=」で、
無理なら、あらゆるコードの前に、
Locale.setDefault(Locale.ROOT); を実行すること。
Struts の ActionServlet が実行される前である必要がある。

上記作業により、既定のロケールが「設定なし」となる。

上記作業が行えない場合、既定のロケールが設定される。
これは実行環境に依存するので注意が必要だ。
日本語環境で動作する機械の場合は、
ja-JP となっていることが多い。

この場合、ja-JP のリソースの優先順位に影響が及ぶので、
ja-JP に対応するリソースを作らない等で回避するしかない。

では、ブラウザの言語設定を変更して試してみよう。
よし、ちゃんと表示された。
英語の方は、JSP の他の部分を英語化していないので、
意味がないが、言語によって切り替わることは確認できた。

今回、EL 式を使ってしまったが、
状況によっては使えない場合がある。

なお、Struts では、複数のメッセージリソースを登録し、
それぞれに個別の名前を付けて参照することもできる。

Actions.properties 等の別のプロパティファイルを定義し、
そこに「allow」か「deny」という単純なキーを使えば、
name 属性と property 属性で取り出すことも可能である。

ただ、この場合プロパティファイルの数が増えてしまうので、
今のところは止めておくことにする。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.