2012-08-17 119 views
1

在servlet中filter,filterChain.doFilter(request,response);應將請求傳遞給下一個鏈中。 但考慮以下兩個代碼:
代碼1:Servlet過濾器模糊不清?

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException 
{ 
filterChain.doFilter(request, response); 
try 
{ 
Thread.sleep(20000); 
} 
catch(Exception e) 
{ 
}    
} 

代碼2:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException 
{ 
try 
{ 
Thread.sleep(20000); 
} 
catch(Exception e) 
{ 
}  
filterChain.doFilter(request, response);  
} 

兩個過濾器執行相同。即兩者在提供請求之前需要20秒。
但實際上應該發生的是Code1應該立即發送,Code2應該在20秒後發送。 爲什麼這種過濾器中的歧義?

回答

3

睡在servlet或過濾器中總是一個壞主意,因爲HTTP工作線程是稀缺資源,因此您不應該阻止它們。但在你的特定例子中,有希望。

基本上,無論您在servlet中打印的內容還是過濾器輸出都隱式緩衝以提高性能。如果您在servlet/filter中打印足夠的數據,servlet容器將刷新緩衝區,並且部分響應將到達客戶端。但你也可以手動刷新!

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { 
    filterChain.doFilter(request, response); 
    response.flushBuffer(); 
    Thread.sleep(20000); 
} 

flushBuffer()指令迫使容器刷新輸出緩衝區。所有響應頭文件以及從servlet發送的任何內容都會發送到客戶端。但這裏有一個問題:客戶端會收到數據,但HTTP連接在接下來的20秒內保持打開狀態。我用curl測試了它,它按預期工作。但是,當瀏覽器使用相同的URL(在Opera,Firefox和Google Chrome上測試)時,瀏覽器會在顯示任何內容之前等待20秒(這可能取決於您實際發送的內容)。

+0

您可以通過顯式關閉與響應關聯的輸出流(或寫入器)來釋放客戶端,但我不相信這是有保證的。 – 2012-08-17 18:43:33