如何将对象从 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?