ユーザ毎にメッセージを切り替えるには
ユーザ毎に表示するメッセージを切り替えたいそうな。例えばenkimiさんがログイン中は金額表示欄のタイトルに「価格」と表示するが、yuukaさんがログイン中は「値段」と表示するというような感じ。Strutsのbean:messageタグを使ってできないか考える。
Strutsのメッセージリソースはロケールに応じて切り替えることができるが、それ以外では切り替わらない。bean:messageタグのbundle属性でメッセージリソースを指定できるが、ログイン中のユーザ毎に自動的に切り替えるという芸当はできない。ModuleConfigのメッセージリソースを置き換えようとしたが、一旦初期化が終わるとfreezeされてしまって置き換えることができない。だがActionServletのprocessメソッドでメッセージリソースをアプリケーションコンテキストから取り出してリクエストにくっつけているのでこれを利用できそう。
まずRequestProcessorのprocessPreprocessメソッドをオーバライド。
public class RequestProcessor extends org.apache.struts.action.RequestProcessor { protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { // getLoginUserName()はセッションやパラメタなどからなんとかしてログインユーザ名を取得するメソッド String loginUserName = getLoginUserName(); MessageResources resources = (MessageResources)getServletContext().getAttribute("org.foo.message." + loginUserName); if (resources == null) { resources = (MessageResources)getServletContext().getAttribute(Globals.MESSAGES_KEY); } request.setAttribute(Globals.MESSAGES_KEY, resources); return true; } }
次にorg/foo/messageに[ユーザ名].propertiesという名前でユーザ毎のメッセージリソースファイルを作成しておく。例えばユーザがenkimiの場合はenkimi.properties。
例:enkimi.properties
kingaku=値段
例:yuuka.properties
kingaku=価格
それ以外にデフォルトのメッセージリソースを用意しておく。これはユーザに対応するメッセージリソースが見つからない場合のデフォルトとして使用される。ApplicationResources.proppertiesを以下のような感じで用意しておく。
kingaku=金額
そしてstruts-config.xmlにメッセージリソースとRequestProcessorを登録。
<controller processorClass="org.foo.struts.RequestProcessor" /> <message-resources parameter="org.foo.message.ApplicationResources" /> <message-resources key="org.foo.message.enkimi" parameter="org.foo.message.enkimi" /> <message-resources key="org.foo.message.yuuka" parameter="org.foo.message.yuuka" />
で、表示用のJSPは普通に
<table border="1"> <tr><th><bean:message key="kingaku"/></th></tr> <tr><td>10,000,000円</td></tr> </table>
でOK。
実行すると、enkimiユーザでログイン中は
値段 |
---|
10,000,000円 |
と表示されるし、yuukaユーザでログイン中は
価格 |
---|
10,000,000円 |
と表示されるし、それ以外のユーザでログイン中の場合は
金額 |
---|
10,000,000円 |
と表示される。できた。