12.9. RESTEasy インターセプター
12.9.1. JAX-RS 呼び出しのインターセプト
概要
RESTEasy は JAX-RS 呼び出しをインターセプトでき、インターセプターと呼ばれるリスナーのようなオブジェクトでルーティングを行います。このトピックでは、インターセプター4種について説明していきます。
例12.3 MessageBodyReader/Writer インターセプター
MessageBodyReaderInterceptors および MessageBodyWriterInterceptors をサーバー側、クライアント側いずれでも利用可能です。RESTEasy がインターセプター一覧に追加するか否かがわかるように
@Provider
と、 @ServerInterceptor
または @ClientInterceptor
がアノテートされます。
これらのインターセプターは、
MessageBodyReader.readFrom()
あるいは MessageBodyWriter.writeTo()
の呼び出しをラップします。また、出力、入力ストリームをラップする際にも利用可能です。
RESTEasy GZIP サポートには、Gzip エンコーディングが機能できるよう、デフォルトの出力、入力ストリームを GzipOutputStream あるいは GzipInputStream で作成しオーバーライドするインターセプターがあります。また、これらのインターセプターを使い、ヘッダーにレスポンスを追加、あるいはクライアント側の送信リクエストを追加できます。
public interface MessageBodyReaderInterceptor { Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException; } public interface MessageBodyWriterInterceptor { void write(MessageBodyWriterContext context) throws IOException, WebApplicationException; }
インターセプターおよび MessageBodyReader/Writer が大きな Java の呼び出しスタックで呼び出されます。次のインターセプターに移動するには、
MessageBodyReaderContext.proceed()
あるいは MessageBodyWriterContext.proceed()
が呼び出され、これ以上呼び出すインターセプターがない場合、MessageBodyReader あるいは MessageBodyWriter の readFrom()
あるいは writeTo()
が呼び出されます。このラッピングにより、オブジェクトがReader あるいは Writer に到達前にオブジェクトを変更することができ、proceed()
を返すまでに消去できます。
以下の例はサーバー側のインターセプターで、ヘッダーの値をレスポンスに追加します。
@Provider @ServerInterceptor public class MyHeaderDecorator implements MessageBodyWriterInterceptor { public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException { context.getHeaders().add("My-Header", "custom"); context.proceed(); } }
例12.4 PreProcessInterceptor
呼び出しが行えるように JAX-RS リソースメソッドを検出してから実際に呼び出す前に、PreProcessInterceptors が実行されます。@ServerInterceptor でアノテーションが付けられ、順番に実行されます。
これらのインターフェースはサーバー上でのみ利用可能です。このインターフェースを使いセキュリティ機能を実装するか、Java リクエストを処理します。RESTEasy セキュリティ実装は、ユーザーが認証情報を渡さない場合に実際に操作が行われる前にインターセプターのこの型を使いリクエストを中断します。RESTEasy のキャッシュフレームワークはこれを使い、キャッシュされたレスポンスを返し、メソッドが再度呼び出されないようにします。
public interface PreProcessInterceptor { ServerResponse preProcess(HttpRequest request, ResourceMethod method) throws Failure, WebApplicationException; }
preProcess()
メソッドは ServerResponse を返し、基礎となる JAX-RS メソッドは呼び出されず、ランタイムがレスポンスを処理しクライアントに返します。preProcess()
メソッドが ServerResponse を返さない場合は、基礎となる JAX-RS メソッドが呼び出されます。
例12.5 PostProcessInterceptors
PostProcessInterceptors は、MessageBodyWriters の呼び出し前かつ JAX-RS メソッドが呼び出された後に実行されます。MessageBodyWriter が呼び出されずレスポンスヘッダーが設定された場合に利用されます。
サーバー側でのみ利用可能です。何もラップしませんが、順番に呼び出されます。
public interface PostProcessInterceptor { void postProcess(ServerResponse response); }
例12.6 ClientExecutionInterceptors
ClientExecutionInterceptors はクライアント側でのみ利用可能です。サーバーに対する HTTP 呼び出し関連でラップを行います。これらは、
@ClientInterceptor
や @Provider
のアノテーションが付けられます。MessageBodyWriter の実行後、および ClientRequest がクライアント側で構築された後に実行されます。
RESTEasy GZIP サポートは、ClientExecutionInterceptors を使いリクエストが出される前に Accept ヘッダーに "gzip, deflate" を含めるよう設定します。RESTEasy のクライアントキャッシュはこれを使い、キャッシュにリソースが含まれているか確認します。
public interface ClientExecutionInterceptor { ClientResponse execute(ClientExecutionContext ctx) throws Exception; } public interface ClientExecutionContext { ClientRequest getRequest(); ClientResponse proceed() throws Exception; }