7

SimpleCaptchaを使用してCAPTCHA入力を作成し、Captcha入力の検証を行いました。次のコードでキャプチャ入力を作成しました。

HTMLコード:

<form action="submit_proceed.do" method="post">
<img src="captchaImg" /><input type="text" name="captcha" value=""><br />
<input type="submit" value="Submit" name="submit" />
</form>

Javaサーブレットコード:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Iterator;
import nl.captcha.Captcha;

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

List errorMsgs = new LinkedList();
try{
    // Validate Captcha
    HttpSession session = request.getSession(true);
    String userCaptcha = request.getParameter("captcha");
    Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
    if (!captcha.isCorrect(userCaptcha)) {
        errorMsgs.add("Please input the correct Captcha value.");
    }
} catch (RuntimeException e) {
    errorMsgs.add("An unexpected error: " + e.getMessage());
    RequestDispatcher view = request.getRequestDispatcher("/error.view");
    view.forward(request, response);
}

しかし、私はこのエラーを受け取り続けました:

StandardWrapperValve[Captcha]: PWC1406: Servlet.service() for servlet Captcha threw exception
java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed

サーブレットでセッションを作成するにはどうすればよいですか?この問題を解決するにはどうすればよいですか?

どうもありがとうございます。

4

6 に答える 6

16

応答がコミットされた後にセッションを作成できない

例外メッセージは非常に明確です。違法国家の手段があります。応答が既にコミットされている場合、応答ヘッダーを設定/変更することはできません。ヘッダーがすでにクライアント側に送信されている場合、応答はコミットされます。これは後戻りできないポイントです。

出力ストリームが直接 (in) フラッシュされるたびに、応答がコミットされます。これは、応答に 2K を超える書き込みを行った場合 (ただし、サーバーの構成によって異なります)、flush()手動で行った場合、またはsendRedirect()呼び出しを行った場合に発生する可能性があります。

セッションを作成する必要があるときはいつでも、サーバーは応答ヘッダーに Cookie を設定して、特定のクライアントを識別し、それをHttpSessionサーバー メモリ内のインスタンスに関連付けることができるようにする必要があります。ただし、応答が既にコミットされている場合は不可能であるため、この例外が発生します。

この問題の根本原因に戻ります。

サーブレット Captcha の Servlet.service() が例外をスローしました

この問題を引き起こしたservlet-nameのは、 のサーブレットです。Captcha要求と応答のチェーン全体をチェック/デバッグして、どのサーブレット/フィルターがすべて呼び出され、サーブレットがセッションを作成する前に応答をコミットした可能性があるものを確認する必要があります。Captchaトピックの開始時にこの情報が欠落しているため、これ以上お手伝いすることはできません。

少なくとも、与えられたコード例では、あなたが不必要にを呼び出していることがわかりますresponse.getWriter()。実際のコードがどのように見えるかはわかりません。おそらくいくつかの行を削除したかもしれませんが、実際にコードを書いている可能性があり、それが問題の根本原因である可能性があります。書きすぎたり、フラッシュしたりすると、応答がコミットされます。コントローラーであるはずのサーブレット内の応答に書き込まないでください。そこでは通常、JSP を使用します。または、デバッグ目的の場合は、 stdout ( System.out.println()) またはLoggerを使用します。

于 2010-01-13T11:42:26.593 に答える
2

問題のコードはnl.captcha.servlet.SimpleCaptchaServletサーブレットにあります。それを変更するとStickyCaptcha問題は解決しますが、具体的には、SimpleCaptcha Servlet の問題のある行は次のとおりです。

CaptchaServletUtil.writeImage(resp, captcha.getImage());
req.getSession().setAttribute(NAME, captcha);

実際には、コードは画像ファイルを応答に書き込んでいます (通常、デフォルトの 2k より大きくなります)。

そのため、当面は を使用するStickyCaptchaか、コードをチェックアウトして問題を修正してください。

于 2011-07-01T09:35:11.490 に答える
1

次の行を移動します。

HttpSession session = request.getSession(true);

doPost メソッドの最初のステートメントになります。

protected void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {

  HttpSession session = request.getSession(true);

  response.setContentType("text/html;charset=UTF-8");

  //...
}

これは役立つはずです。

于 2010-01-13T09:33:36.470 に答える
0

投稿を処理する前に、すでにヘッダーをクライアントに送信しているようです。セッションを作成する場合、サーバーはセッションIDをクライアントに送信する必要があります。これは通常、Cookieを送信することによって行われます。クライアントに何かを送り返す前に、アクション処理を実行するかどうかをコードで確認すると思います。

于 2010-01-13T09:22:19.800 に答える
0

このjavax.servlet.http.HttpSessionsession= request.getSession();を追加してセッションを作成します。


try{ 
 javax.servlet.http.HttpSession session = request.getSession();
    // Validate Captcha 
    String userCaptcha = request.getParameter("captcha"); 
    Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME); 
    if (!captcha.isCorrect(userCaptcha)) { 
        errorMsgs.add("Please input the correct Captcha value."); 
    } 
} catch (RuntimeException e) { 
    ... 
} 
于 2010-01-13T09:25:00.097 に答える
0

この行

 (Captcha) session.getAttribute(Captcha.NAME);

この特定のリクエストが処理される前にセッションがすでに存在している必要があることを意味します。したがって、元のフォームを送信する前に行う必要のある初期化があるのではないかと思います。これは、使用しているフレームワークによって指定する必要があります。

たとえば、最初のセルベットがあります。

 creates the image, figures out the value of Capcha.Name
 creates the session 
 session.setAttribute(Capcha.NAME, theName)
 emit the html (or forward() to a JSP)

これはすべてJSPで行うことも、サーブレットを1つに転送することもできます。

このcatchaライブラリの使用例を調べることができますか?

于 2010-01-13T09:28:36.060 に答える