什么是OncePerRequestFilter?

Som*_*omu 54 spring

文档说org.springframework.web.filter.OncePerRequestFilter" 保证每次请求只执行一次 ".在什么情况下,每个请求可能会多次执行过滤器?

Ste*_*n C 49

在什么情况下,每个请求可能会多次执行过滤器?

您可以在过滤器链上多次使用过滤器.

可以使用请求调度程序将请求分派给不同(或相同)的servlet.


Arm*_*man 18

要了解OncePerRequestFilter的作用,我们首先需要清楚地了解普通过滤器的行为方式.如果希望在servlet执行之前或之后执行某些特定代码,则可以创建一个过滤器,其工作方式如下:

code1   ===>   servlet execution (using chain.doFilter())   ===>    code2
Run Code Online (Sandbox Code Playgroud)

因此,在servlet执行之后,code1在servlet和code2之前执行.但是在这里,当servlet执行时,可能会有一些其他请求到不同的servlet,并且不同的servlet也有这个相同的过滤器.在这种情况下,此过滤器将再次执行.

OncePerRequestFilter可以防止此行为.对于我们的一个请求,此过滤器将只执行一次(不多也不少).使用安全身份验证时,此行为非常有用.

  • 是@Hilikus,请考虑您项目中的常规安全身份验证。我们希望一旦请求到达您的项目,您就应该对其进行一次授权和认证。然后,如果一切正常,则可以允许该请求访问您的API。OncePerRequestFilter确保此身份验证过程仅发生一次。如果不使用它,则每当我们内部对项目中的其他API发出请求时,由于我们所有的API都具有相同的安全筛选器,因此将再次发生相同的身份验证。 (6认同)
  • 您能否详细说明为什么这“在使用安全身份验证时非常有用” (2认同)
  • @Arman “每当我们在内部向项目中的其他 API 发出请求时”,您的意思是每当我们将请求分派/转发到具有相同过滤器的另一个 URL 时,而不仅仅是直接调用该类方法。正确的? (2认同)
  • `这个请求可以被允许访问您的 API。` @arman,您能引用任何示例吗,为什么我们会从一个 api 调用中调用其他 api - 当 servlet 收到请求时,我们可能会调用其他层,例如 service/dao 等,但是那是一个java调用。如果您详细说明您的答案或评论,它将更容易理解。 (2认同)

pc.*_*.97 6

在什么情况下,每个请求可能会多次执行过滤器?


过滤器可以作为单独线程中发生的 REQUEST 或 ASYNC 调度的一部分来调用。我们应该使用 OncePerRequestFilter 因为我们正在执行数据库调用来检索主体或经过身份验证的用户,因此多次执行此操作没有意义。之后,我们将主体设置为安全上下文。

Authentication auth = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
Run Code Online (Sandbox Code Playgroud)

其中 jwtTokenProvider 是用于从 jwt 令牌获取身份验证的服务。