ContainerRequestContextとContainerResponseContext

【前提条件】

[環境]
[参考資料]

JavaEE7 JavaDoc
Java(TM) EE 7 Specification APIs

【概要】

ContainerRequestContextとContainerResponseContextから
何が取得できるかに試してみたのでまとめてみました。

それぞれContainerRequestFilter、ContainerResponseFilterの
パラメータとして渡されます。

【Filterクラスの全体】

import java.io.IOException;
import java.util.List;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;

@Provider
public class SampleFilter implements ContainerRequestFilter, ContainerResponseFilter{

    private static final String SEPARATE_LINE = "=========================================================";

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        // ContainerRequestContextのセクションで後述します。
    }

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        // ContainerResponseContextのセクションで後述します。
    }

今回はContainerのFilterのみを実装しています。

コンソール出力で行を区切るための定数を定義しているだけです。

【ContainerRequestContext】

[ソース]
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        System.out.println(SEPARATE_LINE);
        System.out.println("Request filter start");
        System.out.println(SEPARATE_LINE);

        System.out.println("Method : " + requestContext.getMethod());

        final UriInfo uri = requestContext.getUriInfo();
        System.out.println("Path : " + uri.getPath());
        System.out.println("Absollute Path : " + uri.getAbsolutePath());
        System.out.println("Base Uri : " + uri.getBaseUri());

        final List<String> matchedUriList = uri.getMatchedURIs();
        System.out.println("Uri list");
        for (final String matchedUri : matchedUriList) {
            System.out.println("-Uri : " + matchedUri);
        }

        final List<Object> resourceList = uri.getMatchedResources();
        System.out.println("Resource list");
        for (final Object resource : resourceList) {
            System.out.println("-Resource class : " + resource.getClass().getSimpleName());
        }

        System.out.println(SEPARATE_LINE);
        System.out.println("Request filter end");
        System.out.println(SEPARATE_LINE);
    }
[ContainerRequestContextのメソッド]

ContainerRequestContext#getMethodでリクエストのメソッドが取得できます。
ContainerRequestContextはクッキーの取得、ヘッダー情報の取得できるようです。
ヘッダー情報のいくつかはgetMethodのように専用のメソッドが用意されています。

ContainerRequestContext#getUriInfoで
javax.ws.rs.core.UriInfoクラスのオブジェクトが取得できます。
UriInfoクラスはその名のとおりURIに関する情報を保持するクラスです。

[UriInfoのメソッド]

UriInfo#getPathではコンテキストパスから後のパスが、
UriInfo#getAbsolutePathでは絶対パスが、
UriInfo#getBaseUriではコンテキストパスまでのパスが、
それぞれ取得できます。

UriInfo#getMatchedURIsでは
リソースクラスで指定したパスと一致したパスがリストで返却されます。

UriInfo#getMatchedResourcesでは
実行されるリソースクラスのオブジェクトがリストで返却されます。

何故リストなのかと言うのはJavadocに記述してあります。
UriInfo (Java(TM) EE 7 Specification APIs)

getMatchedURIsはサブリソースがある場合、リストに複数のパスが設定されるようです。
getMatchedResourcesはサブリソースの戻り値がリソースの場合、
リストに複数のオブジェクトが設定されるようです。

[実行結果]

適当なリソースクラスを作成して、ブラウザからアクセスすると
コンソールには↓のような結果が表示されます。
(ここでは前回作ったりソースクラスを呼び出しています)

=========================================================
Request filter start
=========================================================
Method : GET
Path : /filter
Absollute Path : http://localhost:8080/JAX-RS/service/filter
Base Uri : http://localhost:8080/JAX-RS/service/
Uri list
-Uri : http://localhost:8080/JAX-RS/service/filter
Resource list
-Resource class : FilterSampleResource
=========================================================
Request filter end
=========================================================

【ContainerResponseContext】

[ソース]
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {

        System.out.println(SEPARATE_LINE);
        System.out.println("Response filter start");
        System.out.println(SEPARATE_LINE);

        System.out.println("Status : " + responseContext.getStatus());

        final Object entity = responseContext.getEntity();
        System.out.println("Entity class : " + entity.getClass().getSimpleName());
        System.out.println("Entity value : " + entity);

        System.out.println(SEPARATE_LINE);
        System.out.println("Response filter end");
        System.out.println(SEPARATE_LINE);
    }
[ContainerResponseContextのメソッド]

ContainerResponseContext#getStatusでレスポンスのステータスコードが返却されます。

ContainerResponseContext#getEntityでリソースクラスで
レスポンスに設定したエンティティオブジェクトが返却されます。

実行されるリソースクラスでは単純な文字列を
エンティティオブジェクトとして返却しているので、
[Entity Value]の値として出力させています。


ContainerResponseContextはContainerRequestContextと同様に
クッキーの取得、ヘッダー情報の取得できるようです。

[実行結果]

適当なリソースクラスを作成して、ブラウザからアクセスすると
コンソールには↓のような結果が表示されます。
(ここでは前回作ったりソースクラスを呼び出しています)

=========================================================
Response filter start
=========================================================
Status : 200
Entity class : String
Entity value : <html><head><title>Filter Sample</title></head><body>Filter Sample</body></html>
=========================================================
Response filter end
=========================================================

[Entiry Value]には返却するHTMLの内容が出力されているのがわかります。