Top / Struts / org.apache.struts.action.ActionMessage(メッセージ処理)

Strutsのメッセージ処理機構について

Strutsのメッセージ処理を行うActionMessage?の機能について見ていきたいと思います。

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

  • 各エラー情報*1を格納する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?を格納します。実際に受け渡したいメッセージ文言は直接ソースコードで指定することもできる*2し、指定したキー値でリソースファイル内を検索して文言を取得する事もできます。

さて上でリクエストスコープに格納された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が描画されます。

やってみる

実際にアクションクラスでActionMessage?を作成し、その情報をJSPで表示してみたいと思います。

Actionクラス(MessageAction?)

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)

<?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

msg.message1={0}
msg.message2=修飾もできる {0},{1}

# -- standard errors --
errors.header=<ul>
errors.prefix=<li>
errors.suffix=</li>
errors.footer=</ul>

実行結果

上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>

説明。

まずは格納する文言を直接指定する場合

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?*3を順番に取り出して画面に描画していきます。

<html:messages id="message" message="true" >

のmessage属性は、エラーかメッセージかを指定するフラグで、trueの場合は

saveMessages(request, messages);

で渡されたインスタンスで画面を描画します。falseの場合は後述のエラーメッセージ処理で出てくる

saveErrors(request, messages);

で渡されたインスタンスで画面を描画します。

ActionMessages?.GLOBAL_MESSAGEについてはメッセージのグルーピング指定なのですが、後述します。

リソースファイルから文字列を取得する場合

次はリソースファイルからキー値を指定して文字列を取得するパターンです。

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>

が出力さます。

プレースホルダは複数指定できる

プレースホルダは配列を使って複数指定することができます。

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?のグルーピング指定

これまで

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です。

今回はメッセージ処理までまとめました。ほとんど同じなのですがエラー処理については別ページでまとめていこうと思います。

サンプル

TIPS

メッセージがあるときだけ○○

メッセージがあったときだけ何かしたいときなど。

<logic:messagesPresent>エラーが発生しました</logic:messagesPresent>
<logic:messagesNotPresent>エラーなし</logic:messagesNotPresent>

関連リンク


Top / Struts / org.apache.struts.action.ActionMessage(メッセージ処理)

現在のアクセス:50208


*1 エラーじゃなくてもいいんですけどね
*2 ActionMessage?のコンストラクタでフラグをfalseにする
*3 つうか正確にはただのString。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-02-17 (水) 12:07:53 (2658d)