HTTPメソッドを制限するインターセプタ

Java屋はブログ界隈でもコードスニペットあまり書かないよね、と不名誉な事を言われているような気がする。気がするだけで実際そんなことは無いのだが、お堅いJava界隈ではそういう事をするとこいつ下っ端コーダwwとか下流wwと見下す人がまれにいたりするので嫌な感じがします。これも工程別にフェーズ分けし下流は下請け任せ的な大手SI屋主導*1の大規模案件の弊害ですかね。

ま、同じJava屋でもSAStrutsみたいなの使ってるような連中には関係ない世界…、と思っていたのだけど、最近社内のあっちの方でSI屋の真似事しようとしてるのか上流上流と騒いでる。自分たちの望まない方向に会社を進めようとしている勢力がいるようだぞww

それはともかく、SAStrutsでHTTPメソッドを制限するインターセプタを作った。作ってみたものの使わなかったので公開しちゃう。前に一度インターセプタはつくっているので今回はおさらい。

インターセプタ

package your.rootpackage.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;
import org.seasar.struts.util.RequestUtil;
import org.seasar.struts.util.ResponseUtil;

/**
 * SAStrutsのアクションメソッドの実行を、
 * 特定のHTTPメソッドによるアクセスの場合のみに許可するインターセプタです。
 * 許可されないHTTPメソッドでアクセスされた場合、HTTPステータス405を返します。
 *
 */
public class HttpMethodInterceptor extends AbstractInterceptor {

  /**
   * 許可するHTTPメソッド名、カンマ区切りで複数指定可。
   */
  public String value;
  
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {    
    if (this.value != null) {
      HttpServletRequest request = RequestUtil.getRequest();
      String requestMethod = request.getMethod();

      String[] methods = this.value.split(",");
            
      for (String method: methods) {
        if (method.trim().equalsIgnoreCase(requestMethod)) {
          return invocation.proceed();
        }
      }
    }
    
    HttpServletResponse response = ResponseUtil.getResponse();
    response.setStatus(405);
    return null;
  }
}

アノテーション

package your.rootpackage.interceptor;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.seasar.framework.aop.annotation.Interceptor;

/**
 * {@link HttpMethodInterceptor}をSAStrutsのアクションメソッドに適用するアノテーションです。
 * 引数で許可するHTTPメソッドを指定します。カンマ区切りで複数のHTTPメソッドを指定できます。
 * 
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Interceptor("httpMethodInterceptor")
public @interface HttpMethod {	
   String value();
}

使い方

public class AuthAction {
  @Execute(input = "index")
  @HttpMethod("post,get")
  public String login() {
    // 何か処理
  }
}

メソッド実行が拒否された場合、サーブレットコンテナ組み込みのエラーページが表示される。カスタムエラーページを使いたい時は、web.xmlで設定すべし…、と思ったらカスタムエラーページ出ないしwww、インターセプタで例外投げてstruts-configで拾うしかないようだ。

最新版のSAStrutsは、以前ブログでブーたれた部分がいつの間にか改善されていたり、エンティティやサービスが使いやすくなっていたり、自動生成があったり、開発環境がパワーアップしていたり、かなり便利になっていて驚いた。

*1:や、ホントに主導してくれるならいいんだけど、基本的に丸投げで奴ら何もしやがらねえwww