エラー処理を行う場合、遷移先のエラー画面JSPで
<ul> <html:messages id="message"> <li><bean:write name="message" /></li> </html:messages> </ul>
などと書いたりしますが、ActionMessagesを使ったエラー処理の場合と、例外ハンドラを使って処理した場合に出力される内容が違ってたのでいろいろ調べてみました。その調査メモ。
例外ハンドラを使ってJSPに遷移した場合、アクションクラスでせっせとセットしたActionMessageが画面に表示されなかったので、何でかなーと思って調べたのがきっかけです。
まず<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が異なるということですね。
msgにはアクションのActionMessageから取り出した文字列が入ってます。まあ想定通りです。
アクションでせっせと生成した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);
によってあえなく取って替わられることになります。
へぇー。
この記事は
現在のアクセス:18708