ExceptionMappingInterceptorは例外処理のハンドリングをやってくれる。
具体的には、例外を補足して遷移先画面の振り分けを行う。


<package name="example" extends="struts-default">
<global-results>
<result name="error">error.jsp</result>
</global-results>

<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>

<action name="Foo" class="example.FooAction" >
<interceptor-ref name="defaultStack"/>
<exception-mapping exception="example.HogeException" result="hoge_error"/>
<result >/example/Foo.jsp</result>
<result name="hoge_error">/example/hoge_error.jsp</result>
</action>
</package>

上記struts.xmlだと、exampleという名前でグループ化したURLでjava.lang.Exceptionが発生した場合、error.jspに飛ばされる。また、example.FooAction呼び出しの際にexample.HogeExceptionが発生した場合、example/hoge_error.jspに飛ばされる。

ExceptionMappingInterceptorを使用する際に気をつけることは、複数のインターセプターを呼ぶ場合は1番最初に呼び出すようにする。つまり<interceptor-ref name="exception"/>を1番最初に書くようにする。
理由は、ExceptionMappingInterceptorよりも前に別のインターセプターを呼び出し、そのインターセプターで例外が発生しても補足ができないため。

上記struts.xmlでは<interceptor-ref name="exception"/>はどこにも書いてない。理由はstruts-defaultパッケージを継承しており、そこに含まれているdefaultStackを使用しているため。defaultStackには<interceptor-ref name="exception"/>が含まれている。
フレームワークが用意しているinterceptor-stackはすべて<interceptor-ref name="exception"/>が含まれており、大抵のものが先頭に書いてある。

もしフレームワークが用意しているinterceptor-stackを使用せず、インターセプターの定義をすべて自分で書くのであれば<interceptor-ref name="exception"/>を書くことと、書く順番に注意する。

ExceptionMappingInterceptorで補足した例外の内容(Throwable.getMessage)をログに出力したい場合は以下のような書き方をする。

<interceptor-ref name="exception">
<param name="logEnabled">true</param>
<param name="logCategory">jp.co.hogehoge</param>
<param name="logLevel">WARN</param>
</interceptor-ref>

<param name="logEnabled">true</param>は必須で <param name="logLevel">は記載がないとdebugレベルになる。(trace, debug, info, warn, error, fatal以外の値を書くとIllegalArgumentExceptionが発生)

ExceptionMappingInterceptorの処理はexception-mappingのresult要素に関連付けられた画面に飛ばすだけだが、他に何か処理をしたい場合は
publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder)
という拡張ポイントが用意されているのでExceptionMappingInterceptorを継承したクラスを作成し、上記メソッドに処理を書くとよいかもしれない。

0 コメント: