球衣2:过滤器和@Context注入 [英] Jersey 2: filters and @Context injections

查看:106
本文介绍了球衣2:过滤器和@Context注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:

ContainerRequestFilter是一个单例,但请阅读以下内容:

ContainerRequestFilter is a singleton, but reading this:

Jaxrs-2_0 Oracle Spec

在9.2章中,他们说:

in chapter 9.2, they say:

上下文是特定于特定请求的,但是某些JAX-RS组件(具有不同于每个请求的生命周期的提供程序和资源类)的实例可能需要支持多个并发请求.当注入第9.2节中列出的一种类型的实例时,提供的实例必须能够为特定请求选择正确的上下文.使用线程本地代理是实现此目的的常用方法.

Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in Section 9.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.

在9.2章中,没有提到HttpServletRequest.

In the chapter 9.2, the HttpServletRequest is not mentioned.

所以问题是:在并发方面将HttpServletRequest注入自定义的ContainRequestFilter内是否安全?

So the question is: is it safe in terms of concurrency to inject the HttpServletRequest inside a custom ContainRequestFilter?

我的意思是

@Provider
@PreMatching
public class AuthenticationFilter implements ContainerRequestFilter {

   @Context private HttpServletRequest request;  

   @Override
   public void filter(ContainerRequestContext requestContext) throws IOException {
    // This is safe because every thread call the method with its requestContext
    String path = requestContext.getUriInfo().getPath(true);

    // Is this safe? The property request is injected by using @Context annotation (see above)
    String toReturn = (String)request.getAttribute(name);

    [...]
}

我在调试模式下对我的IDE进行了一些经验测试,使用两个不同的浏览器发送了两个不同的并发请求,它似乎运行良好;我注意到过滤器的实例是相同的(单例),但是在两种情况下注入的HttpServletRequest是不同的.

I did some empirical tests on my IDE in debug mode, sending with two different browsers two different and concurrent requests and it seems to work well; I noticed that the filter's instance is ever the same (it's a singleton), but the injected HttpServletRequest is different in the two cases.

我什至阅读了以下主题:如何访问泽西2号请求筛选器发出的wicket会话?,看来我的测试已得到确认.

I readed even this thread: How to access wicket session from Jersey-2 request filter? and it seems that my tests are confirmed.

但是我仍然有疑问.

确认?

推荐答案

是的,这很安全.要了解此问题,您应该了解作用域的工作原理.在处理范围(和注入)的任何框架中,功能都是类似实现的.如果一个对象在单例范围内,而另一个在较小范围内的对象需要注入,则通常将注入该对象的代理.在对象上进行调用时,实际上是在代理上进行调用.

Yes it's safe. To understand the problem, you should understand how scopes work. In any framework that deals with scopes (and injection), the feature is implemented similarly. If an object is in a singleton scope and another object in a lesser scope needs to be injected, usually a proxy of the object will be injected instead. When a call is made on the object, it's actually a call on the proxy.

尽管规范可能没有具体提到HttpServletRequest,但是大多数JAX-RS实现都对此提供了支持.特别是对于Jersey,如果这不可能(意味着该对象不可代理),则在启动时会出现错误消息,内容为不在请求范围内" .原因是ContainerRequestFilter是在应用启动时创建的,并且所有注入也都在该时间处理.如果HttpServletRequest不可代理,它将无法注入,因为在启动时,没有请求范围上下文.

Though the spec may not mention the HttpServletRequest specifically, most JAX-RS implementation have support for this. With Jersey in particular, if this was not possible (meaning the object is not proxiable), then you would get an error message on startup with something like "not within a request scope". The reason is that the ContainerRequestFilter is created on app startup, and all the injections are handled at that time also. If the HttpServletRequest was not proxiable, it would fail to inject because on startup, there is no request scope context.

要确认它不是实际的HttpServletRequest而是代理,可以登录request.getClass(),您会看到它确实是代理.

To confirm that it is not the actual HttpServletRequest and is a proxy, you can log the request.getClass(), and you will see that it is indeed a proxy.

如果您不熟悉此模式,可以查看此答案,以了解其工作原理.

If you are unfamiliar with this pattern, you can see this answer for an idea of how it works.

另请参见:

这篇关于球衣2:过滤器和@Context注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆