如何将自定义上下文绑定到 Jersey 请求

问题描述 投票:0回答:1

我有一个 Jersey REST 应用程序,具有基于令牌的用户身份验证。当请求传入时,将创建一个自定义

RestContext
对象并将其作为属性添加到
ContainerRequestContext
(通过在收到请求后立即运行的过滤器)。此上下文管理用户授权(通过角色)和对其他业务逻辑的访问。它可在资源中用于执行业务逻辑。处理请求后,
RestContext
会在管道末端执行的第二个过滤器中被清理。

虽然需要两个过滤器,但效果很好。我一直在阅读有关 HK2 和

InjectionResolver
的使用的信息,我想知道是否可以使用注入将这个
RestContext
注入到我的资源和其他过滤器中(例如,我有一个过滤器,可以从
SecurityContext
)但我找不到答案。一般来说,如何根据请求上下文为每个请求注入一个对象?这可能吗?有没有更简单的方法,例如使用
RestContext

编辑

:正如所指出的,我基本上试图按照文档的方式在我的资源中注入一个自定义类。但是,我似乎无法正确注册我的 @Context 来绑定我的类的注入。我得到以下信息:


AbstractBinder

编辑

2:我设法取得了一些小小的进展。我通过以下方式创建配置: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=RestContext,parent=RestContextFilter,qualifiers={}),position=0,optional=false,self=false,unqualified=null,1435496015)

因为文档明确指出绑定程序的注入
不支持通过类而是通过实例

但是我现在得到了这个:

new ResourceConfig(allResources()) .packages(packagesToScan()) .registerInstances(new RestContextBinder());

RestContext 在请求/响应过滤器中经过 
A MultiException has 3 exceptions. They are: 1. java.lang.IllegalStateException: Not inside a request scope. 2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of my.package.RestContextFilter errors were found 3. java.lang.IllegalStateException: Unable to perform operation: resolve on my.package.RestContextFilter

编辑。然后它被用来创建一个

@Inject
并将其设置在
SecurityContext
中,并在响应过滤器中被清除。响应过滤器请求没有范围吗?为什么我会收到错误消息?
    

java jersey
1个回答
7
投票
更新

既然 Jersey 2.7 已经出来了,解决方案就更简单了。 听起来您想要一个

ContainerRequestContext

绑定。以下是如何使用 Jersey 2.7 进行设置:

您将需要一个请求过滤器,并且因为 

RequestScoped

将是

RestContext
,您可以将提供程序注入到您的过滤器中,在其上设置一些属性,并知道它们将可用于请求的其余部分。
RequestScoped

您需要注册过滤器并使用 HK2 绑定将 
@Priority(Priorities.AUTHORIZATION) // filter deals with roles, comes after AUTHENTICATION public class RestContextFilter implements ContainerRequestFilter { // you need to inject a provider, rather than the class directly // because this filter is instantiated before the request scope is ready private Provider<RestContext> rcProvider; @Inject public RestContextFilter(Provider<RestContext> rcProvider) { this.rcProvider = rcProvider; } @Override public void filter(ContainerRequestContext requestContext) throws IOException { // now you're in a request scope and can get your context RestContext rc = rcProvider.get(); // set some properties on rc here (current user or roles or whatever) } }

绑定到您的

RestContext
中:
ResourceConfig

然后您可以在资源中注入
public class MyResourceConfig extends ResourceConfig { public MyResourceConfig() { register(RestContextFilter.class); register(new AbstractBinder() { @Override protected void configure() { bindFactory(new Factory<RestContext>() { @Override public RestContext provide() { return new RestContext(); } // this will get called at the end of the request // allowing you to close your request scoped object @Override public void dispose(RestContext instance) { instance.close(); } }, RequestScoped.class).to(RestContext.class).in(RequestScoped.class); } }); } }

,它将包含您的过滤器设置的所有信息。例如:

RestContext

与字段注入相比,我更喜欢构造函数注入,因为我认为这对于阅读您的代码的其他开发人员来说,它使您的依赖关系更加明显。

© www.soinside.com 2019 - 2024. All rights reserved.