// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
**Strutsのメッセージ処理機構について [#zb498008]
Strutsのメッセージ処理を行うActionMessageの機能について見ていきたいと思います。

ActionMessageとはActionクラスで発生したエラー情報(とかなにかメッセージ)をJSPに伝達するための機構です。Actionクラスで発生したエラーをActionMessageというインスタンスに格納することで、JSP側で格納した内容を参照することができます。ActionMessageの機能は以下のモジュールから成っています。。

-各エラー情報((エラーじゃなくてもいいんですけどね))を格納するActionMessage
-ActionMessageのリストを格納するActionMessages
-request,sessionなどのスコープ上に存在するActionMessages内の情報をJSP上で表示するためのタグライブラリ<html:messages>,<html:errors/>


実際の使い方ですがアクションクラス内で
 ActionMessages messages = new ActionMessages(); <-messageを格納するリストを作成
 messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("メッセージ0",false));
としてActionMessageを格納したActionMessagesを作成し、
 saveMessages(request, messages);
としてリクエストスコープにActionMessagesを格納します。実際に受け渡したいメッセージ文言は直接ソースコードで指定することもできる((ActionMessageのコンストラクタでフラグをfalseにする))し、指定したキー値でリソースファイル内を検索して文言を取得する事もできます。

さて上でリクエストスコープに格納されたActionMessageのリストは、JSP側では
 <ul>
 <html:messages id="message" message="true" >
   <li><bean:write name="message" /></li>
 </html:messages>
 </ul>
とすることで画面に表示することができます。上の例だとWEBブラウザには
 <ul>
  <li>メッセージ0</li>
 </ul>
というhtmlが描画されます。


**やってみる [#ofa0913f]
実際にアクションクラスでActionMessageを作成し、その情報をJSPで表示してみたいと思います。

***Actionクラス(MessageAction) [#t06ae08b]
 package nu.mine.kino.strutsexamples.actions;
 
 public class MessageAction extends Action {
   private static final Logger logger = Logger.getLogger(MessageAction.class);
 
   public ActionForward execute(ActionMapping mapping, ActionForm form,
       HttpServletRequest request, HttpServletResponse response)
       throws Exception {
     ActionForward forward = new ActionForward();
     ActionMessages messages = new ActionMessages(); <-messageを格納するリストを作成
 
     // まずは、propertiesからでなく、ココで指定した文字列をそのまま画面表示するパタン。
     messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("メッセージ0",
         false));// リソースフラグをfalseにする。 指定しない場合デフォルトはtrue
 
     // 次はpropertiesから文字列を取得するパタン。"msg.message1"というキー値でpropertiesを検索し、
     // 画面表示。"メッセージ1"は可変文字列で、properties内の
     // msg.message1={0} <-ココが置換される。
     messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
         "msg.message1", "メッセージ1"));
 
     // 可変パラメタは配列もOK。そのばあい
     // msg.message2= {0},{1} などと複数プレースホルダをかける。
     messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
         "msg.message2", new String[] { "メッセージ2の1", "メッセージ2の2" }));
 
     // ActionMessages.GLOBAL_MESSAGEというのはグループのIDになっていて、独自のIDを渡すこともできる。
     // Messageを表示するJSP側で、タグの指定にグループIDを指定すれば、そちらのIDのメッセージを表示可能。
     // 詳細はJSP側で。
     messages.add("HogeGroup", new ActionMessage("別グループのメッセージ", false));
 
     // saveMessageすることで、
     // request.setAttribute(Globals.MESSAGE_KEY, messages);
     // という処理が行われる。
     saveMessages(request, messages);
     return mapping.findForward("success");
 
   }
 }

***JSP(message.jsp) [#z761f468]
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <%@ page language="java" contentType="text/html; charset=UTF-8" %>
 <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
 <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
 <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
 <%@page import="org.apache.struts.action.ActionMessages"%>
 <html:html xhtml="true" lang="true">
 <head>
 <title>ActionMessage系のサンプル</title>
 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
 <html:base />
 </head>
 <body>
 
 <ul>
 <html:messages id="message" message="true" >
   <li><bean:write name="message" /></li>
 </html:messages>
 </ul>
 ↑デフォルトでは、別グループのメッセージは除外しないみたい。
 
 <ul>
 <html:messages id="message" message="true" property="HogeGroup">
   <li><bean:write name="message" /></li>
 </html:messages>
 </ul>
 
 <ul>
 <html:messages id="message" message="true" property="<%=ActionMessages.GLOBAL_MESSAGE%>">
   <li><bean:write name="message" /></li>
 </html:messages>
 </ul>
 ↑別グループのメッセージの除外は、明示的にValueを指定すればいい、、、。
 
 </body>
 </html:html>

***MessageResources.properties [#ud1f7b33]
 msg.message1={0}
 msg.message2=修飾もできる {0},{1}
 
 # -- standard errors --
 errors.header=<ul>
 errors.prefix=<li>
 errors.suffix=</li>
 errors.footer=</ul>


***実行結果 [#uc8c81b3]
上JSPを表示すると以下のようなhtmlが表示されます。
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
 <head>
 <title>ActionMessage系のサンプル</title>
 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
 <base href="http://localhost:8080/strutsExamples/WEB-INF/jsp/message.jsp" />
 </head>
 <body>
 
 <ul>
   <li>メッセージ0</li>
   <li>メッセージ1</li>
   <li>修飾もできる メッセージ2の1,メッセージ2の2</li>
   <li>別グループのメッセージ</li>
 </ul>
 ↑デフォルトでは、別グループのメッセージは除外しないみたい。
 
 <ul>
   <li>別グループのメッセージ</li>
 </ul>
 
 <ul>
   <li>メッセージ0</li>
   <li>メッセージ1</li>
   <li>修飾もできる メッセージ2の1,メッセージ2の2</li>
 </ul>
 ↑別グループのメッセージの除外は、明示的にValueを指定すればいい、、、。
 
 </body>
 </html>

**説明。 [#d00c4d81]
***まずは格納する文言を直接指定する場合 [#df701460]
 messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("メッセージ0", false));
 // リソースフラグをfalseにする。 指定しない場合デフォルトはtrue
ActionMessageのコンストラクタでfalseを指定すると、コンストラクタで指定したStringをそのまま画面に表示することができます。
 saveMessages(request, messages);
このsaveMessagesを実行すると、ActionMessagesがリクエストやセッションスコープにGlobals.MESSAGE_KEYというキー値で格納されます。このキー値で、自前でスクリプトレットなどでhtmlを生成してもよいですが、以下のStrutsのタグライブラリを使って描画するのがよりスマートです。
 <ul>
 <html:messages id="message" message="true" >
   <li><bean:write name="message" /></li>
 </html:messages>
 </ul>
とするとActionMessagesからActionMessage((つうか正確にはただのString。))を順番に取り出して画面に描画していきます。
 <html:messages id="message" message="true" >
のmessage属性は、エラーかメッセージかを指定するフラグで、trueの場合は
 saveMessages(request, messages);
で渡されたインスタンスで画面を描画します。falseの場合は[[後述のエラーメッセージ処理>Struts/org.apache.struts.action.ActionMessage(エラー処理)]]で出てくる
 saveErrors(request, messages);
で渡されたインスタンスで画面を描画します。

ActionMessages.GLOBAL_MESSAGEについてはメッセージのグルーピング指定なのですが、[[後述>Struts/org.apache.struts.action.ActionMessage(メッセージ処理)#z992fe4b]]します。



***リソースファイルから文字列を取得する場合 [#u74ba509]
次はリソースファイルからキー値を指定して文字列を取得するパターンです。
 messages.add(ActionMessages.GLOBAL_MESSAGE, 
  new ActionMessage("msg.message1", "メッセージ1"));
ActionMessageのコンストラクタでフラグを指定しない場合、デフォルトではtrueと見なされリソースファイルから文字列を取得するという指定になります。文字列を取得する際のキー値はActionMessageのコンストラクタの第1引数で指定します。この例はmsg.message1というキー値でリソースファイルを検索しています。第2引数の"メッセージ1"はプレースホルダを置換するさいの文字列です。リソースファイルで
 msg.message1={0}
などと指定しておけば、{0}の箇所が引数で置換されます。従ってhtmlには
 <li>メッセージ1</li>
が出力さます。

***プレースホルダは複数指定できる [#g1de0016]
プレースホルダは配列を使って複数指定することができます。
 messages.add(ActionMessages.GLOBAL_MESSAGE, 
  new ActionMessage("msg.message2", 
    new String[] { "メッセージ2の1", "メッセージ2の2" }));
と複数の置換文字列を指定し、リソースファイルでは
 msg.message2=修飾もできる {0},{1}
としておくと、出力されるhtmlは
 <li>修飾もできる メッセージ2の1,メッセージ2の2</li>
となります。


***ActionMessageのグルーピング指定 [#z992fe4b]
これまで
 messages.add(ActionMessages.GLOBAL_MESSAGE, 
   new ActionMessage("msg.message1", "メッセージ1"));
などと「ActionMessages.GLOBAL_MESSAGE」という値を指定していましたが、これはActionMessageをグルーピングするIDになっています。このIDは任意のIDを渡すことができます。でJSPのタグ側で、そのIDをproperty属性で指定することで、指定したグループのメッセージだけを表示することができます。アクションクラスで
 messages.add("HogeGroup", new ActionMessage("別グループのメッセージ", false));
と指定しておいてmessagesタグで
 <ul>
 <html:messages id="message" message="true" property="HogeGroup">
   <li><bean:write name="message" /></li>
 </html:messages>
 </ul>
と指定すればOKです。



今回はメッセージ処理までまとめました。ほとんど同じなのですがエラー処理については[[別ページ>Struts/org.apache.struts.action.ActionMessage(エラー処理)]]でまとめていこうと思います。




**サンプル [#r8da9621]
-[[サンプルプログラム(ViewVC)>http://www.masatom.in/cgi-bin/viewvc.cgi/tags/V1.0.0_20080119_01/?root=Others]]
-[[サンプルプログラム(Subversion)>https://www.masatom.in/svnsamples/repo/tags/V1.0.0_20080119_01/strutsExamples/]]


**TIPS [#zc8d487c]
***メッセージがあるときだけ○○ [#l5b6ffaf]
メッセージがあったときだけ何かしたいときなど。
 <logic:messagesPresent>エラーが発生しました</logic:messagesPresent>
 <logic:messagesNotPresent>エラーなし</logic:messagesNotPresent>


**関連リンク [#gb56a13e]
-Struts/org.apache.struts.action.ActionMessage(エラー処理)
-[[Javaの道:Struts(15.メッセージ処理)>http://www.javaroad.jp/opensource/js_struts17.htm]]
-[[civic site : Strutsメッセージのまとめ-(2)>http://civic.xrea.jp/2006/09/04/struts-message-2/]]


----
この記事は
#vote(おもしろかった[53],そうでもない[1])

#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS