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());