我发现了一个很好的方法来做到这一点,它不用于在 和 之间进行通信,因为你不能假设响应容器请求的客户端请求将在同一线程上。ThreadLocal
ContainerRequestFilter
ClientRequestFilter
我实现此目的的方法是在 .然后,我可以将对象(显式或通过依赖注入)传递到我的.如果您使用依赖注入(如果您使用的是 Jersey 2,那么您可能使用的是 HK2),那么所有这些都可以在不修改任何资源级别逻辑的情况下实现。ContainerRequestConext
ContainerRequestFilter
ContainerRequestContext
ClientRequestFilter
有一个这样的:ContainerRequestFilter
public class RequestIdContainerFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
containerRequestContext.setProperty("property-name", "any-object-you-like");
}
和 一个在其构造函数中采用一个: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);
}
}
然后,这只是一个将这一切联系在一起的情况。您将需要一个工厂来创建任何或您需要的: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) {
}
}
然后注册过滤器并将工厂绑定到您的主应用程序上:ResourceConfig
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(RequestIdContainerFilter.class);
register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(MyWebTargetFactory.class).to(WebTarget.class);
}
}
}
}