1

サーブレットのフィルターでは、filterChain.doFilter(request, response); リクエストをチェーン内の次のリクエストに渡す必要があります。ただし、次の 2 つのコードを検討してください。
コード 1:

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 秒後にサービスを提供する必要があります。Filter のこのあいまいさはなぜですか?

4

1 に答える 1

3

HTTP ワーカー スレッドはリソースが不足しているため、サーブレットまたはフィルターでスリープすることは常に悪い考えです。したがって、それらをブロックするべきではありません。しかし、あなたの特定の例には希望があります。

基本的に、サーブレットに出力したり出力にフィルターをかけたりするものはすべて、パフォーマンスを向上させるために暗黙的にバッファリングされます。サーブレット/フィルター内に十分なデータを出力すると、サーブレット コンテナーはバッファーをフラッシュし、応答の一部がクライアントに到達します。ただし、手動でフラッシュすることもできます。

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

flushBuffer()命令は、コンテナーに強制的に出力バッファーをフラッシュさせます。すべての応答ヘッダーと、サーブレットから送信したものはすべてクライアントに送信されます。しかし、問題があります。クライアントはデータを受信しますが、HTTP 接続は次の 20 秒間開いたままになります。これをテストしましたがcurl、期待どおりに動作します。ただし、ブラウザーで同じ URL を使用すると (Opera、Firefox、Google Chrome でテスト済み)、ブラウザーは何も表示する前に 20 秒待機します (これは、実際に送信する内容に依存する場合があります)。

于 2012-08-17T17:19:37.577 に答える