如何将对象从 ContainerRequestFilter 传递到资源

Posted

技术标签:

【中文标题】如何将对象从 ContainerRequestFilter 传递到资源【英文标题】:How to Pass Object from ContainerRequestFilter to Resource 【发布时间】:2015-10-30 05:18:44 【问题描述】:

我如何/应该将对象从 ContainerRequestFilter 传递到 (JAX-RS) Resteasy 3.0.11 版中嵌入并使用 Guice 的(匹配后)资源?

【问题讨论】:

【参考方案1】:

方法ContainerRequestContext#setProperty 存储与HttpServletRequest 同步的值。因此,使用普通的 JAX-RS,您可以存储这样的属性:

@Provider
public class SomeFilter implements ContainerRequestFilter 

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException 
        requestContext.setProperty("someProperty", "someValue");
    


然后你可以在你的资源类中获取它:

@GET
public Response someMethod(@Context org.jboss.resteasy.spi.HttpRequest request) 
    return Response.ok(request.getAttribute("someProperty")).build();

使用 CDI,您还可以在过滤器和资源类中注入任何 bean:

@Provider
public class SomeFilter implements ContainerRequestFilter 

    @Inject
    private SomeBean someBean;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException 
        someBean.setFoo("bar");
    


在您的资源类中:

@Inject
private SomeBean someBean;

@GET
public Response someMethod() 
    return Response.ok(someBean.getFoo()).build();

我希望 Guice 也能做到这一点。

更新:正如@bakil 正确指出的那样,如果您要传递的对象应该只与当前请求相关联,您应该使用@RequestScoped bean。

【讨论】:

在 CDI 示例中,我猜 requestContext/request 参数只是分散注意力,我猜 SomeBean 需要注解 @RequestScoped 或类似的? 感谢您的提示。我删除了无意义的参数。 SomeBean 需要是 CDI bean,这意味着它可以具有任何 CDI 范围。 @RequestScoped 在大多数情况下可能是有意义的。 如果使用默认的@Dependent 范围,则过滤器和资源类将接收不同的 SomeBean 实例,因此不会传输数据。我认为您需要@RequestScoped 来确保两者共享同一个实例。 哦,当然,@Dependent 仅在过滤器和资源类具有相同范围的情况下才有效,但情况并非如此。但我试过了,它正在使用 @ApplicationScoped@Singleton@SessionScoped SomeBean(如果这有意义的话)。 不,这些只是看起来有效,但实际上已经坏了。如果您有多个线程同时发出请求,那么您将面临 setFoo/getFoo 混淆的风险。

以上是关于如何将对象从 ContainerRequestFilter 传递到资源的主要内容,如果未能解决你的问题,请参考以下文章

如何将对象从 fetchedResultsController 到 Plist?

如何将 LocationRequest 对象从活动传递到服务?

如何从 XML 的特定部分将 XML 序列化为对象?

如何将对象从 MongoDB 发送到玉?

如何将对象从 windowSWF 传递到 JSFL?

如何以角度将对象从服务返回到组件