質問: JAX-RS (WildflyのRestEasy)でWebサービスを作っています。 自作のアノテーションをWebサービスのメソッドなどに付与して、メソッドが呼ばれる前の共通の処理でそれを識別し、何らかの処理を組み込めるようにしたいです。 ※今回やりたいのはCSRF対策のトークンのチェックを必要とするかどうかを、アノテーションで区別したいだけですが、他にも色々使いたいと考えています。 少なくとも、サーブレットフィルタ `javax.servlet.Filter`を使えば、Webサービスのメソッドの呼び出し前に処理を割り込ませられることは、分かっています。 ただこれだと、「今回のHTTPリクエストで実際に呼び出されるWebサービスのクラスはどれか?」ということが分かりません。 クラスさえ特定できれば、リフレクションでアノテーションを取り出せるので、あとはいくらでもやりようがあるのですが・・・ もちろん、やろうと思えば、アプリケーション全体のクラスから、`@Path`を探したりして解析することはできなくは無いと思いますが、これはJAX-RSがやってくれる処理を再開発することになるので、そこまでやろうとは思いません。 何か良い(標準的な)方法は無いでしょうか?
回答: 多分、標準的なやり方です。 クラスからリフレクションで取らなくても、ContainerRequestFilterを実装したフィルターに対象のアノテーションを追加すれば実現できます。 手順としてはまず、@NameBinding付きのアノテーションを用意します。 ``` @NameBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface VerifyCSRFToken { } ``` これに対応するContainerRequestFilterを追加します。 ``` @VerifyCSRFToken @Provider @Priority(Priorities.AUTHENTICATION) // Priorityは変えても大丈夫です。 public class VerifyCSRFTokenFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { // verify csrf token here } } ``` これでfilterが呼ばれるはずです。 また、@VerifyCSRFTokenのアノテーションなしで実行すると、すべてのリクエストにフィルターが入ります。 すべてのリクエストを取得した上でリフレクションをし検証したい場合、ResourceInfoを使って呼び出されたメソッドを確認できます。 > > ResourceInfo#getResourceMethod() > > 返り値はMethodなので、あとはリフレクションし放題です。 > > > こちらも参考にしてください