Struts2 の Interceptor について。
仕組みについては、http://codezine.jp/article/detail/3264 などを参照。
ここでは、デフォルトで組込まれる Interceptor について、ざっと見ていく。
調査したバージョンは、Struts 2.1.6 (Xwork 2.1.2) である。
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="debugging"/>
<interceptor-ref name="profiling"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
まずは、これだけのデフォルト設定があることを認識する。
ちなみに Interceptor は Struts2 の機能ではなく、Xwork2 の機能だということも覚えておこう。
com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>
<action name="test">
<exception-mapping exception="com.acme.CustomException" result="custom_error"/>
<result name="custom_error">custom_error.ftl</result>
</action>
例外をハンドリングする。
struts.xml に global-exception-mappings もしくは exception-mapping 要素を定義することによって
Exception と Result のマッピングを行うことができる。
何も書かないと、デフォルトでは何もハンドリングされない。
つまり、例外は Struts2 フレームワークを抜けてアプケーションコンテナ(Tomcatなど)に到達する。
com.opensymphony.xwork2.interceptor.AliasInterceptor
<param name="aliases">#{ 'foo' : 'bar' }</param>
<result name="success">good_result.ftl</result>
パラメータのエイリアス(別名)を定義する。
上の例だと、リクエストパラメータに foo があったとき、それを bar に転写する。
つまり、そのアクションに setBar があればそこに foo の値がセットされる。
org.apache.struts2.interceptor.ServletConfigInterceptor
Action が何らかの Aware インターフェイスを実装している場合に、サーブレット関連の値をセットする。
パッケージを見てわかるように、これは Struts2 の Interceptor である。
action.setServletRequest(HttpServletRequest) によってHTTPリクエストをセットする。
action.setServletResponse(HttpServletResponse) によってHTTPレスポンスをセットする。
action.setParameters(Map<String, String[]>) によって、パラメータを一括でセットする。
action.setApplication(Map<String, Object>) によって、アプリケーションのコンテキストパラメータをセットする。
例えば、web.xml に定義した context-param などがここで取得できる。
action.setSession(Map<String, Object> session) によって、Webセッションを格納する値をセットする。
ここで得た session に値を格納することでセッションに値を保存し
次にここから値を取得することでセッションからその値を引き継いで使うことができる。
action.setRequest(Map<String, Object>) によってリクエストの値をセットする。
…らしいが、どうも Struts2 では valueStack が一括で渡されるらしい。
action.setPrincipalProxy(PrincipalProxy) によって認証情報をセットする。
action.setServletContext(ServletContext) によってサーブレットコンテキストをセットする。
ちなみに、通常の ActionSupport はどの Aware も実装していない。
必要に応じて自分で Aware を実装すること。
com.opensymphony.xwork2.interceptor.I18nInterceptor
ロケールを管理する。foo.action?request_locale=en_US のようにすると、このロケールがセッションに保管される。
session.put("WW_TRANS_I18N_LOCALE", locale);
このセッションの値をアクションが利用することで、ユーザにロケールに応じた処理をすることが可能になる。
com.opensymphony.xwork2.interceptor.PrepareInterceptor
アクションに Preparable を実装することで、事前処理を行う。
com.opensymphony.xwork2.interceptor.ChainingInterceptor
value stack にある全てのプロパティを、現在実行中のオブジェクトにコピーする。
chain によって処理を他のアクションに引き継ぐときなどに必要だが、そうでなければ要らない。
org.apache.struts2.interceptor.debugging.DebuggingInterceptor
Struts2 用デバッグモードを有効にする。
ただし、struts.properties に devMode = true と記述しないと有効にはならない。
そして、HTTPリクエストのパラメータに debug を付けると数々の情報が表示される。
http://localhost:8080/Welcome.action?debug=xml
org.apache.struts2.interceptor.ProfilingActivationInterceptor
devMode が有効のとき、HTTPリクエストのパラメータに profile=yes を付けると
Interceptor ごとの処理時間がコンソースにツリー表示される。
ちなみに、defaultStack には多くの Interceptor が登録されているので
必要最小限の Interceptor だけ使うことによってわずかだか処理を高速化できる。
家の環境で試したところ、以下のような結果となった。
defaultStack: 64ms
createSession, servletConfig, profiling のみ: 16ms
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor
ScopedModelDriven を実装したアクションに対して動作するものだが、詳細は不明。
com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor
ModelDriven を実装したアクションに対して動作するものだが、詳細は不明。
org.apache.struts2.interceptor.FileUploadInterceptor
添付ファイルをアップロードするときに使う。
HTML の form タグに enctype="multipart/form-data" を付けたときに稼動する。
詳しい使い方は、Javadoc を参照。
org.apache.struts2.interceptor.CheckboxInterceptor
チェックボックスの初期値を設定するのに使うらしいが、詳細は不明。
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor
<action name="someAction" class="com.examples.SomeAction">
<interceptor-ref name="static-params">
<param name="parse">true</param>
</interceptor-ref>
<result name="success">good_result.ftl</result>
</action>
アクションの初期パラメータ値を設定する。
org.apache.struts2.interceptor.ActionMappingParametersInteceptor
params を継承している。
Struts2 の ActionMapping を使ってパラメータのやりとりをするところだけが異なる。
com.opensymphony.xwork2.interceptor.ParametersInterceptor
これを使うことにより、HTTPリクエストパラメータの値をアクションの Setter に渡すことができる。
com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor
ActionContext インスタンスの conversionErrors に格納されたエラー情報を
フィールドエラーとして扱う。これは ValidationAware で実装される機能。
conversionErrors には、例えば "abc" という値を Integer 型に変換しようとして
失敗した情報などが格納される。
この Interceptor を使うことにより、"abc" という変換前の値を ValidationAware で
扱うことができるようになる。
org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor
Java の Annotation を使ったバリデーション機能を提供する。
com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor
基本的なバリデーション機能のワークフローを提供する。