gpt4 book ai didi

java - Jersey 2 过滤器在客户端请求过滤器中使用容器请求上下文

转载 作者:搜寻专家 更新时间:2023-10-30 21:30:30 24 4
gpt4 key购买 nike

我有一个 Jersey 2 Web 服务,它在收到请求后向另一个 Web 服务发出另一个请求,以形成对原始请求的响应。因此,当客户端“A”向我的 Web 服务“B”发出请求时,“B”向“C”发出请求,作为对“A”的响应的一部分。

A->B->C

我想为 Jersey 2 网络服务实现一个过滤器,它基本上是这样做的:

  • 客户端“A”将发送一个 header 如下的请求“我的标题:第一个”

  • 当我的网络服务“B”发出客户端请求“C”时,它应该附加到该 header ,因此它会发送带有此 header 的请求“我的标题:第一,第二”。

我想将其实现为过滤器,这样我的所有资源就不必重复附加到请求 header 的逻辑。

但是,在 Jersey 2 中,您会得到这 4 个过滤器:

  • ContainerRequestFilter - 过滤/修改入站请求
  • ContainerResponseFilter - 过滤/修改出站响应
  • ClientRequestFilter - 过滤/修改出站请求
  • ClientResponseFilter - 过滤/修改入站响应

Jersey Filter Diagram

我需要使用来自入站请求的 header ,对其进行修改,然后将其用于出站请求,因此本质上我需要既是 ContainerRequestFilter 又是 ClientRequestFilter 的东西。我不认为在同一个过滤器中实现两者会起作用,因为您不知道哪个客户端请求映射到哪个容器请求,或者您知道吗?

最佳答案

我找到了一个很好的方法来做到这一点,它不使用 ThreadLocalContainerRequestFilterClientRequestFilter 之间进行通信,您可以' 假定为响应容器请求而发出的客户端请求将在同一线程上。

我实现这一点的方法是在 ContainerRequestFilterContainerRequestConext 对象中设置一个属性。然后我可以将 ContainerRequestContext 对象(显式或通过依赖项注入(inject))传递到我的 ClientRequestFilter 中。如果您使用依赖注入(inject)(如果您使用的是 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");
}

还有一个 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);
}
}

那么这只是将所有这些捆绑在一起的情况。您将需要一个工厂来创建您需要的任何 ClientWebTarget:

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上注册过滤器并绑定(bind)你的工厂:

public class MyApplication extends ResourceConfig {

public MyApplication() {
register(RequestIdContainerFilter.class);
register(new AbstractBinder() {
@Override
protected void configure() {
bindFactory(MyWebTargetFactory.class).to(WebTarget.class);
}
}
}
}

关于java - Jersey 2 过滤器在客户端请求过滤器中使用容器请求上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24995307/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com