gpt4 book ai didi

java - Jersey 异步 ContainerRequestFilter

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:00:01 25 4
gpt4 key购买 nike

我有一个 Jersey REST API 并且正在使用 ContainerRequestFilter 来处理授权。我还在所有端点上使用 @ManagedAsync,这样我的 API 就可以为数千个并发请求提供服务。

我的授权过滤器命中了一个远程服务,但是当过滤器运行时,Jersey 还没有将当前线程添加到它的内部 ExecutorService,所以我完全失去了异步的好处。

我可以告诉 Jersey 我希望这个 ContainerRequestFilter 是异步的吗?

@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter
{
@Inject
private AuthorizationService authSvc;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
String authToken = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

// HITS A REMOTE SERVER
AuthorizationResponse authResponse = authSvc.authorize(authToken);

if (!authResponse.isAuthorized())
{
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)
.entity("unauthorized!")
.build());
}
}
}

这是一个示例资源:

@Path("/stuff")
@Produces(MediaType.APPLICATION_JSON)
public class StuffResource
{
@GET
@Path("/{id}")
@ManagedAsync
public void getById(@PathParam("id") long id, @Suspended final AsyncResponse ar)
{
Stuff s;

// HIT THE DATABASE FOR STUFF

ar.resume(s);
}
}

更新 刚从 Jersey 的家伙那里听到,从 2.7 开始这是不可能的。只有资源方法本身被异步调用,而不是过滤器。仍然欢迎任何继续进行的建议。

最佳答案

从 2.7 开始,这不是 Jersey 内置的。

@ManagedAsync 如果你有任何过滤器或拦截器做任何严肃的工作(比如点击远程授权服务),那将是无用的。他们可能会在未来添加异步运行过滤器的能力,但现在你只能靠自己了。

更新 - 还有其他方法...

经过漫长而危险的旅程后,我找到了一个短期内使用的非常棘手的解决方案。以下是我尝试过的方法及其失败/成功原因的概要。

Guice AOP - 失败

我将 Guice 用于 DI(让 Guice 注入(inject)与 Jersey 一起工作是一个 feat in itself !),所以我想我可以使用 Guice AOP 来解决这个问题。尽管 Guice 注入(inject)有效,但无法让 Guice 使用 Jersey 2 创建资源类,因此 Guice AOP 无法使用资源类方法。如果您拼命想让 Guice 使用 Jersey 2 创建资源类,不要浪费您的时间,因为它不会工作。这是 well-known problem .

HK2 AOP - 推荐的解决方案

HK2 最近刚刚发布了一个 AOP 功能,请参阅 this question有关如何让它工作的详细信息。

监控 - 也有效

这不适合胆小的人,在 Jersey docs 中完全不鼓励这样做。 .您可以注册 ApplicationEventListener 并覆盖 onRequest 以返回一个 RequestEventListener 来监听 RESOURCE_METHOD_START 并调用身份验证/授权服务。此事件从 @ManagedAsync 线程触发,这是这里的全部目标。需要注意的是,abortWith 方法是空操作,因此它不会像普通的 ContainerRequestFilter 那样工作。相反,如果 auth 失败,您可以抛出异常,并注册一个 ExceptionMapper 来处理您的异常。如果有人足够大胆尝试一下,请告诉我,我会发布代码。

关于java - Jersey 异步 ContainerRequestFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20556200/

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