ogg*_*ter 11 java web-services jersey jersey-client jersey-2.0
我有一个Jersey 2 Web服务,在收到请求后,向另一个Web服务发出另一个请求,以便形成对原始请求的响应.因此,当客户端"A"向我的网络服务"B"发出请求时,"B"向"C"发出请求,作为形成对"A"的响应的一部分.
A-> B-> C ^
我想为Jersey 2 Web服务实现一个基本上执行此操作的过滤器:
客户端"A"将发送一个请求,其标题为"My-Header:first"
当我的Web服务"B"然后发出客户端请求"C"时,它应该附加到该头部,因此它发送一个带有此标题"My-Header:first,second"的请求.
我想将其作为过滤器实现,因此我的所有资源都不必复制附加到请求标头的逻辑.
但是,在Jersey 2中,您可以获得以下4个过滤器:

我需要使用来自入站请求的标头,修改它,然后使用它作为出站请求,所以基本上我需要的东西既是ContainerRequestFilter又是ClientRequestFilter.我不认为在同一个过滤器中实现两者都行不通,因为你不知道哪个客户端请求映射到哪个容器请求,或者你呢?
我找到了一种不错的方法,无需ThreadLocal在ContainerRequestFilter和之间进行通信ClientRequestFilter,因为您不能假定响应容器请求而发出的客户端请求将在同一线程上。
我实现此目标的方法是在中的ContainerRequestConext对象中设置属性ContainerRequestFilter。然后,我可以将ContainerRequestContext对象(显式或依赖注入)传递给我ClientRequestFilter。如果使用依赖项注入(如果使用的是Jersey 2,则可能使用的是HK2),那么无需修改任何资源级别逻辑就可以实现所有这些。
有ContainerRequestFilter这样的:
public class RequestIdContainerFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
containerRequestContext.setProperty("property-name", "any-object-you-like");
}
Run Code Online (Sandbox Code Playgroud)
并且ClientRequestFilter,需要一个ContainerRequestContext在其构造函数:
public class RequestIdClientRequestFilter implements ClientRequestFilter {
private ContainerRequestContext containerRequestContext;
public RequestIdClientRequestFilter(ContainerRequestContext containerRequestContext) {
this.containerRequestContext = containerRequestContext;
}
@Override
public void filter(ClientRequestContext clientRequestContext) throws IOException {
String value = containerRequestContext.getProperty("property-name");
clientRequestContext.getHeaders().putSingle("MyHeader", value);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,这只是将它们绑在一起的一种情况。您将需要一个工厂来创建任何Client或所需的工厂WebTarget:
public class MyWebTargetFactory implements Factory<WebTarget> {
@Context
private ContainerRequestContext containerRequestContext;
@Inject
public MyWebTargetFactory(ContainerRequestContext containerRequestContext) {
this.containerRequestContext = containerRequestContext;
}
@Override
public WebTarget provide() {
Client client = ClientBuilder.newClient();
client.register(new RequestIdClientRequestFilter(containerRequestContext));
return client.target("path/to/api");
}
@Override
public void dispose(WebTarget target) {
}
}
Run Code Online (Sandbox Code Playgroud)
然后注册过滤器,并将您的工厂绑定到您的主应用程序上ResourceConfig:
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(RequestIdContainerFilter.class);
register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(MyWebTargetFactory.class).to(WebTarget.class);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15653 次 |
| 最近记录: |