java.lang.IllegalStateException: Kann nicht (vorwärts | sendRedirect | erstellen Sitzung) nach Reaktion begangen wurde

StackOverflow https://stackoverflow.com/questions/2123514

Frage

Dieses Verfahren wirft

  

java.lang.IllegalStateException: Kann nicht vorwärts nach Reaktion begangen wurde,

, und ich bin nicht in der Lage, das Problem zu erkennen. Jede Hilfe?

    int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
    String chkboxVal = "";
    // String FormatId=null;
    Vector vRow = new Vector();
    Vector vRow1 = new Vector();
    String GroupId = "";
    String GroupDesc = "";
    for (int i = 0; i < noOfRows; i++) {
        if ((request.getParameter("chk_select" + i)) == null) {
            chkboxVal = "notticked";
        } else {
            chkboxVal = request.getParameter("chk_select" + i);
            if (chkboxVal.equals("ticked")) {
                fwdurl = "true";
                Statement st1 = con.createStatement();
                GroupId = request.getParameter("GroupId" + i);
                GroupDesc = request.getParameter("GroupDesc" + i);
                ResultSet rs1 = st1
                        .executeQuery("select FileId,Description from cs2k_Files "
                                + " where FileId like 'M%' and co_code = "
                                + ccode);
                ResultSetMetaData rsm = rs1.getMetaData();
                int cCount = rsm.getColumnCount();

                while (rs1.next()) {
                    Vector vCol1 = new Vector();
                    for (int j = 1; j <= cCount; j++) {
                        vCol1.addElement(rs1.getObject(j));
                    }
                    vRow.addElement(vCol1);
                }
                rs1 = st1
                        .executeQuery("select FileId,NotAllowed from cs2kGroupSub "
                                + " where FileId like 'M%' and GroupId = '"
                                + GroupId + "'" + " and co_code = " + ccode);
                rsm = rs1.getMetaData();
                cCount = rsm.getColumnCount();

                while (rs1.next()) {
                    Vector vCol2 = new Vector();
                    for (int j = 1; j <= cCount; j++) {
                        vCol2.addElement(rs1.getObject(j));
                    }
                    vRow1.addElement(vCol2);
                }

                // throw new Exception("test");

                break;
            }
        }
    }
    if (fwdurl.equals("true")) {
        // throw new Exception("test");
        // response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
        request.setAttribute("GroupId", GroupId);
        request.setAttribute("GroupDesc", GroupDesc);
        request.setAttribute("vRow", vRow);
        request.setAttribute("vRow1", vRow1);
        getServletConfig().getServletContext().getRequestDispatcher(
                "/GroupCopiedUpdt.jsp").forward(request, response);
    }
War es hilfreich?

Lösung

Ein weit verbreitetes Missverständnis unter den Startern ist, dass sie denken, dass der Ruf eines forward(), sendRedirect() oder sendError() magisch würde verlassen und „Sprung“ aus dem Verfahrensblock, hiermit den Rest des Codes zu ignorieren. Zum Beispiel:

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    }
    forward(); // This is STILL invoked when someCondition is true!
}

Dies ist also eigentlich nicht wahr. Sie wissen nicht sicher verhalten sich anders als alle anderen Java-Methoden (erwarten von System#exit() natürlich). Wenn die someCondition in obigem Beispiel true ist und Sie somit forward() nach sendRedirect() oder sendError() auf dem gleichen Request / Response-Aufruf, dann ist die Chance, groß , dass Sie die Ausnahme erhalten:

  

java.lang.IllegalStateException: Kann nicht vorwärts nach Reaktion begangen wurde,

Wenn die if Anweisung eine forward() ruft und Sie danach sendRedirect() oder sendError() aufrufen, dann wird unter Ausnahme ausgelöst werden:

  

java.lang.IllegalStateException: Kann nicht nennen sendRedirect (), nachdem die Reaktion begangen wurde,

Um dies zu beheben, müssen Sie entweder eine return; Aussage danach

hinzufügen
protected void doPost() {
    if (someCondition) {
        sendRedirect();
        return;
    }
    forward();
}

... oder einen anderen Block einzuführen.

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    } else {
        forward();
    }
}

Um die Ursache in Ihrem Code Naildown, suchen Sie einfach für jede Zeile, die ein forward(), sendRedirect() oder sendError() ruft, ohne den Verfahrensblock zu verlassen oder den Rest des Codes zu überspringen. Dies kann innerhalb des gleichen Servlet vor dem bestimmten Codezeile, sondern auch in jedem Servlet oder Filter, die vor dem bestimmten Servlet aufgerufen worden waren.

Bei sendError(), wenn Ihr einziger Zweck ist es, anstatt den Antwortstatus, Verwendung setStatus() zu setzen.


Eine weitere mögliche Ursache ist, dass das Servlet die Antwort schreibt, während ein forward() aufgerufen wird, oder hat in der gleichen Methode aufgerufen wurde.

protected void doPost() {
    out.write("some string");
    // ... 
    forward(); // Fail!
}

Die Antwortpuffergröße Standardwerte in den meisten Server 2 KB, also, wenn Sie mehr als 2 KB, um es zu schreiben, dann werden sie begangen und forward() die gleiche Art und Weise fehlschlagen:

  

java.lang.IllegalStateException: Kann nicht vorwärts nach Reaktion begangen wurde,

Lösung liegt auf der Hand, schreiben Sie einfach nicht auf die Antwort im Servlet. Das ist die Verantwortung der JSP. Sie legen ein Anforderungsattribut wie so request.setAttribute("data", "some string") und drucken Sie es dann in JSP wie so ${data}. Siehe auch unsere Servlets Wikiseite zu lernen, wie Servlets, den richtigen Weg zu verwenden.


Noch eine weitere mögliche Ursache ist, dass der forward(), sendRedirect() oder sendError() Methoden werden über Java-Code eingebettet in einer JSP-Datei in Form von altmodischer Weise <% scriptlets %> aufgerufen, eine Praxis, die war offiziell seit 2001 entmutigen. Zum Beispiel:

<!DOCTYPE html>
<html lang="en">
    <head>
        ... 
    </head>
    <body>
        ...

        <% sendRedirect(); %>

        ...
    </body>
</html>

Das Problem hierbei ist, dass JSP intern sofort Schablonentext- (das heißt HTML-Code) über out.write("<!DOCTYPE html> ... etc ...") so schnell schreibt, wie es aufgetreten ist. Dies ist also im Wesentlichen das gleiche Problem wie in der vorhergehenden Abschnitt erläutert.

Lösung liegt auf der Hand, schreiben Sie einfach nicht Java-Code in einer JSP-Datei. Das ist die Verantwortung einer normalen Java-Klasse wie ein Servlet oder einen Filter. Siehe auch unsere Servlets Wikiseite zu lernen, wie Servlets, den richtigen Weg zu verwenden.


Siehe auch:


Nicht verwandte , um Ihre concrete Problem, JDBC-Code undicht Ressourcen. Fix das auch. Für Hinweise finden Sie auch, wie oft Verbindung , Statement und ResultSet in JDBC geschlossen werden?

Andere Tipps

auch eine return-Anweisung Zugabe bringt diese Ausnahme nach oben, für die einzige Lösung dieser Code:

if(!response.isCommitted())
// Place another redirection

Normalerweise sehen Sie diesen Fehler, nachdem Sie bereits eine Umleitung getan haben, und versuchen Sie dann die Ausgabe einige weitere Daten in den Ausgabestream. In den Fällen, in denen ich in der Vergangenheit gesehen haben, ist es oft eines der Filter, der die Seite umzuleiten versucht, und dann noch nach vorne bis zum Servlet. Ich kann nichts sofort falsch mit dem Servlet sehen, so dass Sie versuchen möchten vielleicht einen Blick auf irgendwelchen Filtern mit, dass Sie an der richtigen Stelle auch.

Bearbeiten : Einige weitere Hilfe in Diagnose des Problems ...

Der erste Schritt dieses Problem zu diagnostizieren ist, genau zu ermitteln, wo die Ausnahme ausgelöst wird. Wir gehen davon aus, dass es durch die Linie geworfen wird

getServletConfig().getServletContext()
                  .getRequestDispatcher("/GroupCopiedUpdt.jsp")
                  .forward(request, response);

Aber Sie können feststellen, dass es später im Code geworfen wird, wo Sie an den Ausgangsstrom versuchen, nachdem Sie versucht haben, die nach vorn zu tun. Wenn es aus der obigen Linie kommt, dann bedeutet es, dass irgendwo vor dieser Zeile haben Sie entweder:

  1. Ausgangsdaten an den Ausgangsstrom oder
  2. vorher eine andere Umleitung erfolgen.

Viel Glück!

Das ist, weil Ihr Servlet versucht, ein Request-Objekt zuzugreifen, die nicht mehr existiert, ist .. Ein Servlet ist nach vorne oder Erklärung nicht enthalten die Ausführung des Verfahrens Block zu stoppen. Weiter geht es bis zum Ende des Verfahrensblockes oder ersten return-Anweisung wie jede andere Java-Methode.

Der beste Weg, um dieses Problem zu beheben, setzen Sie einfach die Seite (wo Sie die Anfrage weiterleiten nehmen an) Ihre Logik dynamisch entsprechend. Das heißt:

protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
 returnPage="page1.jsp";
}
if(condition2){
   returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}

und tut das nach vorne nur einmal am letzten Zeile ...

Sie können auch dieses Problem beheben mit return-Anweisung nach jedem vorwärts () oder setzen jeweils nach vorne () in if ... else Block

I entfernt

        super.service(req, res);

Dann funktionierte es gut für mich

Bump ...

ich den gleichen Fehler nur hatte. Ich bemerkte, dass ich super.doPost(request, response); wurde aufgerufen wird, wenn die doPost() Methode überschrieben sowie explizit die übergeordnete Klasse Aufruf Konstruktor

    public ScheduleServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

Sobald ich bemerkte aus dem super.doPost(request, response); aus doPost() Aussage es funktionierte perfekt ...

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

        //super.doPost(request, response);
        // More code here...

}

Unnötig zu sagen, ich brauche auf super() Best Practices erneut zu lesen: p

Sie sollten hinzufügen Rückkehr Erklärung während Sie weiterleiten oder den Fluss umgeleitet wird.

Beispiel:

Wenn forwardind,

    request.getRequestDispatcher("/abs.jsp").forward(request, response);
    return;

Wenn Umleiten,

    response.sendRedirect(roundTripURI);
    return;

Nach der Rückkehr Forward-Methode können Sie einfach tun:

return null;

Es wird den aktuellen Bereich brechen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top