2017-06-21 61 views
2

我正在開發基於Spring啓動的應用程序。我注意到,對於異步端點,認證過濾器被調用兩次,對於常規端點,它被調用一次。我找不到原因,但我在網絡https://jira.spring.io/browse/SPR-12608中發現了一個問題,它表示在異步端點執行前後,異步端點的過濾器被調用了兩次。這將解釋雙重身份驗證呼叫。我想知道這是預期的行爲,爲什麼這樣做,以及如何避免雙重身份驗證。爲什麼篩選器鏈被稱爲異步端點兩次

UPD: 我發現了一種方法,在異步終結點完成後,如何避免過濾器第二次觸發。我需要做的是分析哪種調度程序分配給請求,如果它是異步的 - 繼續進行過濾器鏈。我添加下面的方法來過濾:

@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); 
    } 
} 

回答

1

我看到完全一樣的行爲,我認爲這是關係到一個事實,即異步調用將分爲2個階段。

首先,普通容器線程被踢,併產生臨時響應,但該響應沒有被返回到客戶端,直到異步調度器競爭爲止。一旦異步線程完成,處理臨時響應將被異步線程中的真實線程替換並返回給客戶端。

兩個線程都通過相同的過濾器鏈。因此你會看到重複的調用。

如果你希望你的過濾器被調用一次,你應該擴展OncePerRequestFilter。它會檢查你的過濾器是否在請求過程中被調用過(即使請求處理包含2個階段,每個階段都由它們自己的線程處理)。