Top/Struts/ActionMessagesによるエラー処理と、例外ハンドラで処理した場合の挙動の違い

エラー処理を行う場合、遷移先のエラー画面JSPで

<ul>
<html:messages id="message">
  <li><bean:write name="message" /></li>
</html:messages>
</ul>

などと書いたりしますが、ActionMessagesを使ったエラー処理の場合と、例外ハンドラを使って処理した場合に出力される内容が違ってたのでいろいろ調べてみました。その調査メモ。

例外ハンドラを使ってJSPに遷移した場合、アクションクラスでせっせとセットしたActionMessageが画面に表示されなかったので、何でかなーと思って調べたのがきっかけです。

まずは<bean:write name="message" /> から

まず<bean:write name="message" /> のmessageというオブジェクトはだれがどう生成してるのかを調べてみました。これは巡り巡って<html:messages>のタグクラスであるMessagesTagの

MessagesTag.processMessage(ActionMessage)

内の275行目あたりにある

pageContext.setAttribute(id, msg);
id:上のid属性の値(message),
msg: html画面上に表示される文言(型はString)

のmsgオブジェクトでした。すでにStringなんですね*1

さてこのMessageTag.processMessage(ActionMessage)のActionMessageインスタンスですが、通常のアクションクラスでエラー情報をセットしたActionMessageが使われる場合と、例外ハンドラによって処理されたActionMessageが渡ってくる場合があることが分かりました。つまり待ち受けてるJSPが同じ

<ul>
<html:messages id="message">
  <li><bean:write name="message" /></li>
</html:messages>
</ul>

だとしても、遷移元の処理の違いによって、渡されるActionMessageが異なるということですね。

通常のアクションクラスでセットしたActionMessage(s)を表示する場合

msgにはアクションのActionMessageから取り出した文字列が入ってます。まあ想定通りです。

例外ハンドラによって生成されたActionMessage(s)を表示する場合

アクションでせっせと生成したActionMessageは渡ってきませんね。

調べたところorg.apache.struts.action.ExceptionHandlerクラスの

ExceptionHandler#execute(Exception, ExceptionConfig, ActionMapping, 
          ActionForm, HttpServletRequest, HttpServletResponse)

内(147行目あたり)で、

error = new ActionMessage(ae.getKey(), ex.getMessage());

とされていました。ae.getKey()はstruts-config.xmlで指定されたキー値*2、ex.getMessage()は例外クラスのgetMessageですね*3。あーなるほどだからstruts-config.xmlのキー値でプロパティ内を探しに行き、{0}を例外のメッセージでプレースホルダしてたんですね。理解できました。さらにこのあとにExceptionHandler#storeException内で

protected void storeException(HttpServletRequest request, String property,
  ActionMessage error, ActionForward forward, String scope) {
  ActionMessages errors = new ActionMessages();

  errors.add(property, error);

  if ("request".equals(scope)) {
    request.setAttribute(Globals.ERROR_KEY, errors);
  } else {
    request.getSession().setAttribute(Globals.ERROR_KEY, errors);
  }
}

され、ActionでセットしたActionMessagesは

request.setAttribute(Globals.ERROR_KEY, errors);

によってあえなく取って替わられることになります。

へぇー。


この記事は

選択肢 投票
おもしろかった 23  
そうでもない 31  
Top/Struts/ActionMessagesによるエラー処理と、例外ハンドラで処理した場合の挙動の違い

現在のアクセス:18708


*1 これがActionMessageの数だけぐるぐる回る感じ
*2 aeは引数のExceptionConfigです
*3 exは引数のExceptionです

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2026-07-15 (水) 00:03:24