Develop with pleasure!

福岡でCloudとかBlockchainとか。

Struts2で例外を捕捉する

Struts Classicの時はAction内で発生した例外は、ExceptionHandlerで捕捉していたが、Struts2からは例外の捕捉もInterceptorが行う。
ExceptionMappingInterceptorというInterceptorがその役割をする。ちなみにこのクラスsturts-coreではなく、xwork2のjarに含まれてる。

このInterceptorのおかげで、stuts.xmlに以下のように例外のマッピング定義をしておけば、定義された例外が発生した際に、定義されたresultの内容が実行される。

<global-results>
  <result name="exception" type="velocity">exception.html</result>
</global-results>
<global-exception-mappings>
  <exception-mapping exception="java.lang.Exception" result="exception"/>
</global-exception-mappings>

まぁ、例外種別によって制御が行われるのは良いけど、例えばその例外情報をログ出力したいとかいった場合、Struts ClassicのExceptionHandlerだとクラス内でログ出力が簡単にできてたが、Struts2からはInterceptorによりさせられるので途中でフックして処理を注入するのが面倒な気がする。

フックしたい場合は主に2通りの方法があると思う。
1つはresultタグで定義する際に、typeをchainにしてAcitonクラスにフォワードするという方法。(例外捕捉用のActionを別に作っておく。)

ただ、<せっかくglobal-exception-mappings>を定義して各Exception毎にresultの定義が反映されるのに、それらの先が全て例外捕捉用のActionになってしまう。そしておそらくそのAction内で例外毎の処理や遷移先の判断をするようになってしまう。

これはちょっとイケテない。

2つ目の方法は、ExceptionMappingInterceptorを継承したInterceptorを作成し、その中で必要な処理をして、その後の遷移は、の定義内容に委譲するという方法。これだとstruts.xmlに適用するinterceptorの定義を変更する必要はあるが、Struts2が持っているはそのまま利用できる。

まぁ、後は、SpringのAOPでExceptionMappingInterceptorのinterceptメソッドをインターセプトするといった方法でも可能かも。