#author("2024-01-11T04:02:58+00:00","","") #author("2024-01-29T08:39:12+00:00","","") // 下階層用テンプレート #topicpath ---- //ここにコンテンツを記述します。 #contents エラー処理を行う場合、遷移先のエラー画面JSPで <ul> <html:messages id="message"> <li><bean:write name="message" /></li> </html:messages> </ul> などと書いたりしますが、ActionMessagesを使ったエラー処理の場合と、例外ハンドラを使って処理した場合に出力される内容が違ってたのでいろいろ調べてみました。その調査メモ。 例外ハンドラを使ってJSPに遷移した場合、アクションクラスでせっせとセットしたActionMessageが画面に表示されなかったので、何でかなーと思って調べたのがきっかけです。 **まずは<bean:write name="message" /> から [#i8c30779] まず<bean:write name="message" /> のmessageというオブジェクトはだれがどう生成してるのかを調べてみました。これは巡り巡って<html:messages>のタグクラスであるMessagesTagの MessagesTag.processMessage(ActionMessage) 内の275行目あたりにある pageContext.setAttribute(id, msg); id:上のid属性の値(message), msg: html画面上に表示される文言(型はString) のmsgオブジェクトでした。すでにStringなんですね((これがActionMessageの数だけぐるぐる回る感じ))。 さてこのMessageTag.processMessage(ActionMessage)のActionMessageインスタンスですが、通常のアクションクラスでエラー情報をセットしたActionMessageが使われる場合と、例外ハンドラによって処理されたActionMessageが渡ってくる場合があることが分かりました。つまり待ち受けてるJSPが同じ <ul> <html:messages id="message"> <li><bean:write name="message" /></li> </html:messages> </ul> だとしても、遷移元の処理の違いによって、渡されるActionMessageが異なるということですね。 **通常のアクションクラスでセットしたActionMessage(s)を表示する場合 [#gd61dbb0] msgにはアクションのActionMessageから取り出した文字列が入ってます。まあ想定通りです。 **例外ハンドラによって生成されたActionMessage(s)を表示する場合 [#d4418472] アクションでせっせと生成した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で指定されたキー値((aeは引数のExceptionConfigです))、ex.getMessage()は例外クラスのgetMessageですね((exは引数のExceptionです))。あーなるほどだから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); によってあえなく取って替わられることになります。 へぇー。 ---- この記事は #vote(おもしろかった[23],そうでもない[30]) #vote(おもしろかった[23],そうでもない[31]) #comment #topicpath SIZE(10){現在のアクセス:&counter;}