Java(Seasar2)のSAStrutsで、Actionメソッドの前処理・後処理として、ログの出力や、認証チェック処理などの共通的な処理を入れたい。
そんな場合は、「Interceptor(インターセプター)」とやらを使用すれば楽にできるみたい。
とりあえずやってみた。
なお、今回のバージョンは以下です。
- Eclipse 4.2 Juno
- JDK 7u15
- Apache Tomcat 7.0.35
AbstractInterceptorクラスを継承したインターセプタークラスの作成
まずは、「AbstractInterceptor」クラスを継承し、「invoke」をオーバーライドさせる。
今回は、クラス名を「ActionInterceptor」とした。
以下のように、「Object object = invocation.proceed();」の部分で、Actionなどの制御に移るらしく、ここより前に処理を書けば前処理に、後ろに処理を書けば後処理になる。
なお、ここでは「Executeアノテーション(@Execute)」がついているActionメソッドかどうかを判定している。
「Executeアノテーション(@Execute)」がついているActionメソッドのみを対象としないと、全てのメソッドが引っかかってしまい、不要なログまで出ていたので。
Actionメソッドならほぼ全部に「Executeアノテーション(@Execute)」がついているはず。
package jp.co.sample.interceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.log4j.Logger; import org.seasar.framework.aop.interceptors.AbstractInterceptor; import org.seasar.struts.annotation.Execute; public class ActionInterceptor extends AbstractInterceptor { // 変数 Logger logger = Logger.getLogger(getClass()); @Override public Object invoke(MethodInvocation invocation) throws Throwable { // Executeアノテーションの場合 if (isExecuteMethod(invocation)) { // 前処理 before(invocation); } // 主処理 Object object = invocation.proceed(); // Executeアノテーションの場合 if (isExecuteMethod(invocation)) { // 後処理 after(invocation); } return object; } private String getActionName(MethodInvocation invocation) { // 変数 String className; String methodName; String actionName; // アクション名取得 className = getTargetClass(invocation).getSimpleName(); methodName = invocation.getMethod().getName(); actionName = className + "#" + methodName; // アクション名返却 return actionName; } private Boolean isExecuteMethod(MethodInvocation invocation) { // Executeアノテーション真偽値返却 return invocation.getMethod().isAnnotationPresent(Execute.class); } private void before(MethodInvocation invocation) { // ログ出力 logger.info(getActionName(invocation) + "を開始します。"); } private void after(MethodInvocation invocation) { // ログ出力 logger.info(getActionName(invocation) + "を終了します。"); } }app.diconにインターセプターを登録
続いて、上記で作成したインターセプターを「app.dicon」ファイルに登録する。
「app.dicon」ファイルの場所は、「/プロジェクト名/src/main/resources/app.dicon」。
実際の書き方はこんな感じ。
1行追加しただけ。
<!--?xml version="1.0" encoding="UTF-8"?--> <components> <include path="convention.dicon"> <include path="aop.dicon"> <include path="j2ee.dicon"> <include path="s2jdbc.dicon"> <component name="actionMessagesThrowsInterceptor" class="org.seasar.struts.interceptor.ActionMessagesThrowsInterceptor"> <component name="actionInterceptor" class="jp.co.sample.interceptor.ActionInterceptor"> </component></component></include></include></include></include></components>customizer.diconにインターセプターを追加
最後に、上記で作成したインターセプターを「customizer.dicon」ファイルに追加する。
「customizer.dicon」ファイルの場所は、「/プロジェクト名/src/main/resources/customizer.dicon」。
追加する場所は、「actionCustomizer」の下に「addCustomizer」で追加する。
以下のような感じ。
<!--?xml version="1.0" encoding="UTF-8"?--> <components> <include path="default-customizer.dicon"></include></components> <component name="formCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"> <component name="actionCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"> <initmethod name="addAspectCustomizer"> <arg>"actionMessagesThrowsInterceptor"</arg> </initmethod> <initmethod name="addCustomizer"> <arg>traceCustomizer</arg> </initmethod> <initmethod name="addCustomizer"> <arg> <component class="org.seasar.framework.container.customizer.TxAttributeCustomizer"> </component></arg> </initmethod> <initmethod name="addCustomizer"> <arg> <component class="org.seasar.struts.customizer.ActionCustomizer"> </component></arg> </initmethod> <initmethod name="addCustomizer"> <arg> <component class="org.seasar.framework.container.customizer.AspectCustomizer"> <property name="interceptorName">"actionInterceptor"</property> <property name="pointcut">".*"</property> <property name="useLookupAdapter">false</property> </component> </arg> </initmethod> </component> <component name="serviceCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"> <initmethod name="addCustomizer"> <arg>traceCustomizer</arg> </initmethod> <initmethod name="addCustomizer"> <arg> <component class="org.seasar.framework.container.customizer.TxAttributeCustomizer"> </component></arg> </initmethod> </component>動作確認
以上の設定で、動作を確認してみる。
以下のように、無事に目的のログが出力されていました。
INFO 2013-12-17 21:52:31,669 [http-bio-8080-exec-4] IndexAction#indexを開始します。 INFO 2013-12-17 21:52:31,669 [http-bio-8080-exec-4] IndexAction#indexを終了します。 INFO 2013-12-17 21:52:31,963 [http-bio-8080-exec-6] LoginAction#Indexを開始します。 INFO 2013-12-17 21:52:31,963 [http-bio-8080-exec-6] LoginAction#Indexを終了します。なお、Log4Jに関しては、こちらの記事参照⇒「Java(Seasar2)で「Log4J」によるログ出力の設定」
参考サイト
コメント