为什么为异步端点两次调用过滤器链 [英] Why filter chain is called twice for an asynchronous endpoint

查看:173
本文介绍了为什么为异步端点两次调用过滤器链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发基于Spring Boot的应用程序.我注意到,对于异步端点,身份验证过滤器被调用两次,对于常规端点,它被调用一次.我找不到原因,但在网络 https://jira中发现了一个问题. spring.io/browse/SPR-12608 ,据说异步端点的过滤器在异步端点执行之前和之后都会被调用两次.它将解释双重身份验证调用.我想知道这是预期的行为,为什么要那样做以及如何避免双重身份验证.

I'm developing a Spring boot based app. I noticed that for asynchronous endpoints authentication filter is called twice, for regular endpoints it's called once. I couldn't find the reason, but I found an issue in the net https://jira.spring.io/browse/SPR-12608 , where it's said that filters for async endpoints are called twice, before and after async endpoint execution. It would explain double authentication call. I'd like to know is this expected behavior, why it's done like that and how to avoid double authentication.

UPD: 我找到了一种方法来避免在异步终结点完成后再次触发筛选器.我需要做的是分析哪种分配器分配给请求(如果它是异步的)-在过滤器链上继续进行.我在过滤器中添加了以下方法:

UPD: I found a way how to avoid filter being firing second time after async endpoint finished. The thing I need to do is to analyse what kind of dispatcher is assigned to the request, if it's async - proceed further on filter chain. I added the following method to the filter:

@Override
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
    if (request.getDispatcherType() == DispatcherType.ASYNC) {
        filterChain.doFilter(request, response);
    } else {
        super.doFilter(request, response, filterChain);
    }
}

推荐答案

我看到的行为完全相同,我认为这与将异步调用分为两个阶段这一事实有关.

I am seeing exactly the same behavior and I think it is related to the fact that asynchronous call is being split into 2 phases.

首先,常规容器线程被踢出并生成临时响应,但是该响应不会返回给客户端,它会一直保留到异步调度程序竞争为止.一旦异步线程完成,处理临时响应就会被来自异步线程的真实响应替换,并返回给客户端.

At first, regular container thread is kicked and an interim response is generated, but that response is not being returned to the client it is being held back until async dispatcher competes. Once async thread is done processing interim response is replaced with the real one from async thread and returned to the client.

两个线程都经过相同的过滤器链.因此,您会看到重复的调用.

Both threads go through the same filter chain. Therefore you see duplicate invocation.

如果要一次调用过滤器,则应从OncePerRequestFilter扩展.它将检查在请求过程中是否已经调用了过滤器(即使请求处理包括2个阶段,每个阶段都由自己的线程处理).

If you want your filter to be invoked once you should extend from OncePerRequestFilter. It will check if your filter was already invoked during the course of the request (even though the request handling consists of 2 stages each of them handled by their own threads).

这篇关于为什么为异步端点两次调用过滤器链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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