当前位置: 首页 > 知识库问答 >
问题:

泽西2每个请求@上下文注入

沈弘盛
2023-03-14

在Jersey 2中,我可以将一个定制的、请求特定的值注入到我的资源中吗?具体来说,我想注入一个< code>MyThing,它可以从我的自定义安全上下文< code>MySecurityContext中派生出来。我想直接注入< code>MyThing来使代码变得干净。

有什么办法可以做到这一点吗?根据这个问题,它不能使用上下文解析器来完成,尽管本文和此示例表明它可能是可能的。

使用身份验证筛选器,我可以使用以下代码设置自定义安全上下文:

@Provider
public class HttpTokenAuthFilter implements IComposableJaxRsAuthFilter {

   @Override
   public boolean doAuth(ContainerRequestContext requestContext) throws WebApplicationException {
       // error handling omitted
       requestContext.setSecurityContext(MySecurityContext.fromHeaders(requestContext));
   }
}

...然后在我的资源中,我可以从中提取一个值:

@Path("/foo")
public class MyResource {
    @Context 
    private SecurityContext securityContext;

    @Get
    public String doGetFoo() {
       MyThing myThing = ((MySecurityContext)securityContext).getThing();
       // use myThing to produce a result
    }

...但是,由于这将重复很多次,我宁愿只写:

    @Context
    private MyThing myThing;

我尝试定义ContextResolver。我看到它被构造出来,但我从未看到它被调用,所以我还没有尝试过上述任何技术。这就是要使用的正确类吗?

@Provider
public class MyThingResolver implements ContextResolver<MyThing> {

    public MyThingResolver() {
        System.out.println("ctor");
    }

    @Override
    public MyThing getContext(Class type) {
        System.out.println("getContext");

        if (type.equals(MyThing.class)) {
           return new MyThing(); // TODO: SHOULD ACTUALLY USE CURRENT MySession
        }
        return null;
    }
}

共有1个答案

於德馨
2023-03-14

根据这个答案和这个后续中指定的改进,几乎有可能使用工厂完成注射。唯一需要注意的是,您必须通过提供程序注入MyThing,否则它将在过滤器运行之前创建(使用默认的安全上下文)并在我的安全上下文中交换。

工厂代码如下:

public class MyThingFactory implements Factory<MyThing> {

    @Context
    private SecurityContext securityContext;

    @Override
    public MyThing provide() {
        return ((MySecurityContext)securityContext).getThing();
    }

    @Override
        public void dispose(MyThing session) {
    }
}

然后资源可以像这样注入它:

@Context
private Provider<MyThing> myThingProvider;

…像这样消费它:

MyThing myThing = myThingProvider.get();
// use myThing

AbstractBinder中的工厂注册如下:

this.bindFactory(MyThingFactory.class) //
    .to(MyThing.class) //
    .in(RequestScoped.class);

根据@peeskillet的评论,可以通过代理MyThing来删除提供商。(因此,根据@jwells131313,MyThing必须是接口或可代理类。)

绑定看起来如下所示:

this.bindFactory(MyThingFactory.class) //
    .to(MyThing.class) //
    .proxy(true) //
    .in(RequestScoped.class);

注射最终按预期工作:

@Context
private MyThing myThing;
 类似资料:
  • 我有一个RESTfulendpoint,我通过一个定制的ContainerRequestFilter用一个简单的授权检查来保护它。过滤器检查HTTP会话中包含的所有信息是否正确,如果不正确,则执行以下操作: 这一切都很好。奇怪的是,当我再次发出相同的GET请求时,泽西服务器报告了一个NPE并且没有返回任何东西。 NPE 堆栈跟踪: 发生了什么?我不想关闭输出流。我只需要一个方法向请求者返回http

  • 有人成功部署了Jersey 2吗。带JBoss 7的x。x?我曾尝试在JBoss 7.1.1中部署Jersey 2.5,但遇到以下错误: 我认为这个问题是因为JBoss与RestEasy捆绑在一起,RestEasy是一个JAX-RS 1.0实现,而Jersey是一个JAX-RS 2.0实现。因此,我采取以下步骤禁用RestEasy: 1)在我的web.xml中添加了以下内容: 2)按照这里的讨论,

  • 我有一个基于令牌的用户身份验证的Jersey REST应用程序。当请求传入时,会创建一个自定义的对象,并将其作为一个属性添加到 的用法,我想知道是否可以使用injection将这个< code>RestContext注入到我的资源和其他过滤器中(例如,我有一个过滤器,它从< code>RestContext中创建一个< code>SecurityContext),但是我找不到答案。一般来说,我如何

  • 要查看此问题的完整代码,请参阅此github https://github.com/mobiusinversion/web-application 我正在使用Jersey 2.15开发。这是一个嵌入式的Jetty应用程序,它被遮蔽到一个单独的罐子中。 在防波堤起动器(主类)中: 我有一个通过提供程序包含的过滤器 则在筛选器中:

  • 我有灰熊提供的球衣。 我有一个实现类。但是,为所有传入请求创建一次此类。因此,这样做: 为空。我可以将上下文注入到被调用的实际endpoint中,但这相当粗糙和丑陋,对我来说真的没有用;因为我希望记录各种请求。理想情况下,希望在请求的ResponseFilter端找到这个对象。 必须有一种简单的方法来做到这一点。到目前为止,我看到的所有问题/答案都不适用于灰熊,或者注入了RESTendpoint调

  • 这件事已经做了几个小时了,似乎什么也做不成。它是Jersey 2.23.2。我想将一个基于请求的Hibernate会话注入Jersey提供程序,以便在我的REST API中使用。相反,我得到的是: 这是我的代码: 我已经尝试了上百种排列方式。不知疲倦地在网上搜索。因为我一直没有明确地看着这个问题,所以我认为它一定很简单。 当我在 AbstractBinder 配置方法中指定单例而不是请求范围时,我