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 接口 复制链接链接已复制到粘贴板!
ClientRequestFilter 的 过滤器 方法接收单个参数,即 javax.ws.rs.client.ClientRequestContext,它可用于访问传出请求消息及其关联的元数据。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.Client 对象上注册客户端请求过滤器,或者在 javax.ws.rs.client.WebTarget 对象上注册。实际上,这意味着客户端请求过滤器可以选择性地应用到不同的范围,因此只有特定 URI 路径会受到过滤器的影响。
例如,以下代码演示了如何注册 SampleClientRequestFilter 过滤器,以将它应用到使用 客户端 对象进行的所有调用;以及如何注册 TestAbortClientRequest 过滤器,使它仅应用到 rest/TestAbortClientRequest 的子路径。
// 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());