107 votes

java.lang.IllegalStateException : Impossible (forward | sendRedirect | create session) après que la réponse ait été validée.

Cette méthode lance

java.lang.IllegalStateException : Impossible d'avancer après que la réponse ait été validée

et je ne parviens pas à identifier le problème. Vous pouvez m'aider ?

    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);
    }

4 votes

C'est difficile à voir comme ça, mais il semble que vous ayez déjà envoyé une sortie avant votre avant. Pourriez-vous imprimer le code complet et vérifier que vous n'avez pas de filtre en place ?

266voto

BalusC Points 498232

Un malentendu commun parmi les partants, c'est qu'ils pensent que l'appel d'un forward() ou sendRedirect() serait comme par magie de sortie et de "sauter" de la méthode de bloc, par les présentes, en ignorant le reste du code. Par exemple:

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

C'est donc en fait pas vrai. Ils le font certainement pas de se comporter différemment de toutes les autres méthodes de Java (attendez-vous à de la System#exit() bien sûr). Lorsque l' someCondition dans l'exemple ci-dessus est - true, puis la chance est grande que vous obtiendrez une IllegalStateException: Cannot forward after response has been committed. C'est indépendamment de si l' if déclaration appelle un sendRedirect() ou forward().

Pour résoudre ce problème, vous devez ajouter un return; énoncé par la suite

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

... ou pour introduire un bloc else.

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

Pour naildown la cause racine dans votre code, il suffit de chercher pour n'importe quelle ligne qui appelle une sendRedirect() ou forward() sans sortir de la méthode de bloquer ou de sauter le reste du code. Cela peut être à l'intérieur de la même servlet avant la ligne de code, mais aussi dans une servlet ou un filtre qui a été appelé avant la servlet particulier.

Sans rapport avec votre problème: votre code JDBC est une fuite de ressources. Correctif.

2 votes

Avec une pause, vous voulez dire break; ? Cela signifierait que le code a été placé à l'intérieur d'un for o while boucle dans laquelle le forward() a été appelé à plusieurs reprises pendant la boucle (ce qui est donc incorrect, vous ne devriez appeler forward qu'une fois APRÈS la boucle -- ou pour vous débarrasser de la boucle car elle n'est apparemment pas nécessaire).

0 votes

@BalusC Avez-vous une idée sur ce problème connexe ? stackoverflow.com/questions/18658021/

0 votes

@confile : Je ne fais pas de Grails, mais d'après la pile d'appels, il effectue toujours un forward() appel alors qu'il ne devrait pas le faire. JSF, avec lequel je suis familier, fait aussi cela à moins que vous n'appeliez explicitement FacesContext#responseComplete() . Cette question connexe (que j'ai trouvée en utilisant les mots clés "grails prevent render response") peut être utile : stackoverflow.com/questions/5708654/

20voto

user1503117 Points 121

Même l'ajout d'une déclaration de retour fait apparaître cette exception, pour laquelle la seule solution est ce code :

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

6voto

Paul Wagland Points 10487

En général, vous voyez cette erreur après avoir effectué une redirection et essayé d'envoyer d'autres données vers le flux de sortie. Dans les cas où j'ai vu cela dans le passé, il s'agissait souvent d'un des filtres qui essayait de rediriger la page, et qui transmettait toujours à la servlet. Je ne vois pas de problème immédiat avec la servlet, donc vous pourriez essayer de jeter un coup d'oeil à tous les filtres que vous avez mis en place également.

Modifier : Un peu plus d'aide pour diagnostiquer le problème

La première étape du diagnostic de ce problème consiste à déterminer l'endroit exact où l'exception est levée. Nous supposons qu'elle est déclenchée par la ligne

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

Mais il se peut que vous trouviez qu'il est lancé plus tard dans le code, lorsque vous essayez de sortir sur le flux de sortie après avoir essayé de faire le forward. Si cela vient de la ligne ci-dessus, cela signifie que quelque part avant cette ligne vous avez soit :

  1. les données de sortie vers le flux de sortie, ou
  2. fait une autre redirection au préalable.

Bonne chance !

2voto

Ashish Mishra Points 1

Vous devez ajouter retourner pendant que vous transférez ou redirigez le flux.

Exemple :

si forwardind,

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

si on redirige,

    response.sendRedirect(roundTripURI);
    return;

2voto

Suman Sengupta Points 36

C'est parce que votre servlet essaie d'accéder à un objet de requête qui n'existe plus L'instruction forward ou include d'une servlet n'arrête pas l'exécution du bloc méthode. Elle continue jusqu'à la fin du bloc de méthode ou jusqu'à la première déclaration de retour, comme toute autre méthode Java.

La meilleure façon de résoudre ce problème est de définir la page (où vous devez transférer la demande) de façon dynamique selon votre logique. C'est-à-dire :

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
}

et faire le forward une seule fois à la dernière ligne...

Vous pouvez également résoudre ce problème en utilisant l'instruction return après chaque forward() ou en plaçant chaque forward() dans un bloc if...else.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X