Stripes Framework どうよ。その3 〜Interceptorあるよ。

引き続きStripesです。
StripesにもInterceptorの機能が標準であり、色んなフェーズに共通の処理を差しこめるわけです。

package selva2;

import jp.sf.amateras.mirage.integration.guice.Transactional;
import jp.sf.amateras.mirage.session.Session;
import jp.sf.amateras.mirage.session.SessionFactory;
import net.sourceforge.stripes.controller.Interceptor;
import net.sourceforge.stripes.controller.Intercepts;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.controller.ExecutionContext;

@Intercepts(LifecycleStage.EventHandling)
public class TxInterceptor implements Interceptor {
    public Resolution intercept(ExecutionContext ctx) throws Exception {

        Resolution proceed = null;

        if (ctx.getHandler().getAnnotation(Transactional.class) == null) {
            proceed = ctx.proceed();
            return proceed;
        }

        Session session = SessionFactory.getSession();
        session.begin();

        try {
            proceed = ctx.proceed();
            session.commit();
        } catch (Exception e) {
            session.rollback();
            throw e;
        } finally {
            session.release();
        }
        return proceed;
    }
}

上の例は、ActionBeanのメソッドに対して、トランザクション処理を実行する例です(mirage使ってます)。Transactionalアノテーションがメソッドに付けられてる場合のみトランザクションが有効になるようにしています。
enumのLifecycleStageで、どこのフェーズでインターセプタ―を有効にするか複数指定できます。バリデーション時とか、Resolutionの実行時とか。

package action.twitter;

import jp.sf.amateras.mirage.integration.guice.Transactional;
import dao.tweet.TweetDao;
import entity.Tweet;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.validation.Validate;

public class TweetActionBean extends TopPageActionBean {

    @Validate(required=true)
    protected String status;

    @Transactional
    @DefaultHandler
    public Resolution defaultHandler() {
        Tweet tweet = new Tweet();
        tweet.setStatus(status);
        new TweetDao().insert(tweet);
        return redirect(ListActionBean.class);
    }
    // setter, getter割愛
}

Transactionalアノテーションを付けたActionBeanクラスのメソッドの例

web.xmlでInterceptorを設定しておく必要があります。

  <filter>
    <display-name>Stripes Filter</display-name>
    <filter-name>StripesFilter</filter-name>
    <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
    :
    :
    <init-param>
      <param-name>Interceptor.Classes</param-name>
      <param-value>selva2.TxInterceptor</param-value>
    </init-param>
  </filter>

ちなみに、JTAとか使わないこんなレベルで(ry

以上