1

誰か助けてください。

 private void forward(String address,
                    HttpServletRequest  request,
                    HttpServletResponse response)
                        throws ServletException, IOException{
    getServletContext()
        .getRequestDispatcher("/" + address)
        .forward(request, response);
}
private void include(String address,
                    HttpServletRequest  request,
                    HttpServletResponse response)
                        throws ServletException, IOException{
    getServletContext()
        .getRequestDispatcher("/" + address)
        .include(request, response);
}

これらの 2 つの関数は、私のプロジェクトのすべてのサーブレットに記述されています。問題は、これらの 2 つの関数を最初にサーブレットで使用したときに、include("servlet/abc",request.response); ということです。forward("servlet/def",request.response); を使用した後 したがって、Netbeans 7を使用して、フォワードがサーブレットのコントロールを転送していないことを段階的に監視しましたが、フォワードの前にインクルードを使用しない場合、コントロールを転送します。

なぜそれが起こっているのか、その理由と、サーブレットを含めた後にどうすれば転送できるのかを知りたいです。

誰か助けてください...興味深い質問です。

include("servlet/abc",request, response);


forward("servlet/def",request, response);   //HERE IS PROBLEM NOT FORWRDING AFTER INCLUDE
4

3 に答える 3

7

この動作を観察しているように見える正確な理由に関係なく、試行していることは機能しません。RequestDispatcher.forward()のコントラクトに従って、「応答がすでにコミットされている場合、このメソッドはIllegalStateExceptionをスローします」、および「応答バッファー内のコミットされていない出力は、転送前に自動的にクリアされます。」

したがって、転送が成功したかどうかに関係なく、転送の前後の両方でコンテンツをユーザーに正常に送り返すことはできません。これは、転送の目的が「1つのサーブレットが要求の予備処理を実行し、別のリソースが応答を生成する」ことを許可することであり、2つの異なるサーブレットが応答の異なる部分を生成することを許可しないためです。サーブレットモデルでは、応答の生成は常に1つのサーブレットにのみ属します。

「コミット済み」と「非コミット済み」の意味がわからない場合は、応答ステータスとヘッダーがまだユーザーに送信されているかどうかを示しています。応答を書き込んでいるときは、実際にはローカルバッファに書き込んでいます。必ずしもすぐに送信されるわけではありません。書き込んだ内容がすべてローカルである限り、転送のようにバッファのリセットや最初からやり直すなど、何でも自由に行うことができますが、何かが送信されるとすぐにコミットされ、それ以上できなくなります。あなたがやろうとしていたことを変えなさい。応答は、より多くのコンテンツのためのスペースを確保するために送信する必要があるようにバッファをいっぱいにするなど、いくつかの方法でコミットされる(つまり、すべてまたは一部がユーザーに送信される)可能性があります。手動で、または応答のWriterまたはOutputStreamをフラッシュします。

最終的に、あなたのケースでおそらく起こっていることは、インクルードを使用して何かを書いていることであり、バッファをいっぱいにしたか、インクルードが一般的に自動を引き起こすことを思い出したために、応答がコミットされる原因になっていますフラッシュ(これに関するドキュメントについてはわかりません)。次に、転送しようとすると、必要なIllegalStateExceptionがスローされます。これは、おそらくログのどこかに表示されますが、すでに説明したように、他のステータスでコミットしているため、通常の500応答ステータスは発生しません。コード。

于 2012-12-30T06:29:15.713 に答える
2

応答がコミットされると、応答のステータスまたは状態を変更することはできません。リクエストディスパッチャーを使用してページを含めると、実際にはレスポンスがコミットされ、データがクライアントに送信され始めます。その後、リダイレクトに必要な 302 への応答ステータスの変更を行うことはできません。

しようとするとエラーになりますjava.lang.IllegalStateException: Cannot forward after response has been committed

于 2012-12-30T05:01:45.400 に答える
0

RequestDispatcher には次の 2 つのメソッドしかありません。

public interface javax.servlet.RequestDispatcher {
  public abstract void forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) throws javax.servlet.ServletException, java.io.IOException;
  public abstract void include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) throws javax.servlet.ServletException, java.io.IOException;
}

あなたはそれを次のように与えています

include("servlet/abc",request, response);
forward("servlet/def",request, response);

しかし、APIでは、サーブレットリクエストオブジェクトとレスポンスオブジェクトのみがパラメーターとして言及されているため、そこからURLを削除する必要があると思います. 私も勉強中なので間違っていたらごめんなさい。

于 2013-09-25T20:26:47.240 に答える