Menu Close

61.4. クライアントリクエストフィルター

概要

本セクションでは、クライアント側で送信リクエストメッセージをインターセプトするために使用されるクライアントリクエストフィルターを実装および登録する方法を説明します。クライアントリクエストフィルターは、多くの場合でヘッダーの処理に使用され、あらゆる種類の汎用リクエスト処理に使用できます。

ClientRequestFilter インターフェース

javax.ws.rs.client.ClientRequestFilter インターフェースは以下のように定義されます。

// Java
package javax.ws.rs.client;
...
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientRequestContext;
...
public interface ClientRequestFilter {
    void filter(ClientRequestContext requestContext) throws IOException;
}

ClientRequestFilter を実装することにより、クライアント側に ClientRequest エクステンションポイントのフィルターを作成できます。これは、メッセージをサーバーに送信する前にリクエストメッセージをフィルタリングします。

ClientRequestContext インターフェース

ClientRequestFilterfilter メソッドは、javax.ws.rs.client.ClientRequestContext 型の引数を 1 つ受け取り、これは送信リクエストメッセージとその関連メタデータにアクセスするために使用できます。ClientRequestContext インターフェースは以下のように定義されます。

// Java
...
package javax.ws.rs.client;

import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyWriter;

public interface ClientRequestContext {

    public Object getProperty(String name);

    public Collection<String> getPropertyNames();

    public void setProperty(String name, Object object);

    public void removeProperty(String name);

    public URI getUri();

    public void setUri(URI uri);

    public String getMethod();

    public void setMethod(String method);

    public MultivaluedMap<String, Object> getHeaders();

    public abstract MultivaluedMap<String, String> getStringHeaders();

    public String getHeaderString(String name);

    public Date getDate();

    public Locale getLanguage();

    public MediaType getMediaType();

    public List<MediaType> getAcceptableMediaTypes();

    public List<Locale> getAcceptableLanguages();

    public Map<String, Cookie> getCookies();

    public boolean hasEntity();

    public Object getEntity();

    public Class<?> getEntityClass();

    public Type getEntityType();

    public void setEntity(final Object entity);

    public void setEntity(
            final Object entity,
            final Annotation[] annotations,
            final MediaType mediaType);

    public Annotation[] getEntityAnnotations();

    public OutputStream getEntityStream();

    public void setEntityStream(OutputStream outputStream);

    public Client getClient();

    public Configuration getConfiguration();

    public void abortWith(Response response);
}

実装例

ClientRequest エクステンションポイント (リクエストメッセージを送信する前にフィルターが実行される場所) にクライアントリクエストフィルターを実装するには、ClientRequestFilter インターフェースを実装するクラスを定義します。

たとえば、以下のコードは、ClientRequest エクステンションポイントにインストールされる単純なクライアントリクエストフィルターの例を示しています。ここで、優先度は 20 になります。

// Java
package org.jboss.fuse.example;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.annotation.Priority;

@Priority(value = 20)
public class SampleClientRequestFilter implements ClientRequestFilter {

  public SampleClientRequestFilter() {
    System.out.println("SampleClientRequestFilter starting up");
  }

  @Override
  public void filter(ClientRequestContext requestContext) {
    System.out.println("ClientRequestFilter.filter() invoked");
  }
}

呼び出しの中止

適切なクライアントリクエストフィルターを実装してクライアント側の呼び出しを中止できます。たとえば、クライアント側のフィルターを実装して、リクエストが正しくフォーマットされているかどうかをチェックし、必要な場合はリクエストを中止できます。

以下のテストコードは常に リクエストを中止し、BAD_REQUEST HTTP ステータスをクライアント呼び出しコードに返します。

// Java
package org.jboss.fuse.example;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.annotation.Priority;

@Priority(value = 10)
public class TestAbortClientRequestFilter implements ClientRequestFilter {

  public TestAbortClientRequestFilter() {
    System.out.println("TestAbortClientRequestFilter starting up");
  }

  @Override
  public void filter(ClientRequestContext requestContext) {
    // Test filter: aborts with BAD_REQUEST status
    requestContext.abortWith(Response.status(Status.BAD_REQUEST).build());
  }
}

クライアントリクエストフィルターの登録

JAX-RS 2.0 クライアント API を使用すると、クライアントリクエストフィルターを javax.ws.rs.client.Client オブジェクトまたは javax.ws.rs.client.WebTarget オブジェクトに直接登録できます。実質的に、クライアントリクエストフィルターはオプションで異なるスコープに適用でき、特定の URI パスのみがフィルターの影響を受けます。

たとえば、次のコードは、client オブジェクトを使用して行われたすべての呼び出しに適用されるように SampleClientRequestFilter フィルターを登録する方法、および rest/TestAbortClientRequest のサブパスにのみ適用されるように TestAbortClientRequestFilter フィルターを登録する方法を示しています。

// Java
...
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
...
Client client = ClientBuilder.newClient();
client.register(new SampleClientRequestFilter());
WebTarget target = client
  .target("http://localhost:8001/rest/TestAbortClientRequest");
target.register(new TestAbortClientRequestFilter());