Ява.ленг.IllegalStateException: не удается (forward | sendRedirect / create session) после фиксации ответа


этот метод выдает

java.ленг.IllegalStateException: не удается переслать после того, как ответ был совершен

и я не могу определить проблему. Какая-нибудь помощь?

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

8 ответов:

распространенное недоразумение среди начинающих заключается в том, что они думают, что вызов forward(),sendRedirect() или sendError() волшебным образом выйдет и" выпрыгнет " из блока метода, тем самым игнорируя остаток кода. Например:

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

это, таким образом, на самом деле не так. Они, конечно, не ведут себя иначе, чем любые другие методы Java (ожидайте System#exit() конечно). Когда someCondition в приведенном выше примере это true и ты так называть forward() после sendRedirect() или sendError() на тот же запрос/ответ, то шанс большой что вы получите исключение:

java.ленг.IllegalStateException: не удается переслать после того, как ответ был совершен

если if оператор вызывает a forward() а ты потом звонишь sendRedirect() или sendError(), то ниже исключение будет брошено:

java.ленг.IllegalStateException: не удается вызвать sendRedirect() после ответа было совершено

чтобы исправить это, вам нужно либо добавить return; заявление после

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

... или ввести блок else.

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

чтобы прибить основную причину в вашем коде, просто найдите любую строку, которая вызывает a forward(),sendRedirect() или sendError() без выхода из блока метода или пропуска остатка кода. Это может быть внутри того же сервлета перед конкретной строкой кода, но также и в любом сервлете или фильтре который был вызван перед конкретным сервлетом.

в случае sendError(), если ваша единственная цель-установить статус ответа, используйте .


другая вероятная причина заключается в том, что сервлет записывает ответ в то время как forward() будет вызван, или был вызван в том же самом методе.

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

размер буфера ответа по умолчанию на большинстве серверов составляет 2 КБ, поэтому если вы пишете на него более 2 кб, то он будет зафиксирован и forward() провалится так же:

java.ленг.IllegalStateException: не удается переслать после того, как ответ был совершен

решение очевидно, просто не пишите в ответ в сервлет. Это ответственность JSP. Вы просто устанавливаете атрибут запроса так request.setAttribute("data", "some string") а затем распечатать его в JSP, как так ${data}. Смотрите также наша страница Вики сервлетов чтобы узнать, как правильно использовать сервлеты.

посмотреть также:


связаны к вашей конкретной проблеме, ваш код JDBC утечка ресурсов. Исправь и это тоже. Для подсказок см. также как часто должны быть закрыты соединение, оператор и результирующий набор в JDBC?

даже добавление оператора return вызывает это исключение, для которого единственным решением является этот код:

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

обычно вы видите эту ошибку после того, как вы уже сделали перенаправление, а затем попытаетесь вывести еще несколько данных в выходной поток. В тех случаях, когда я видел это в прошлом, это часто один из фильтров, который пытается перенаправить страницу, а затем все еще переходит к сервлету. Я не вижу ничего сразу не так с сервлетом, так что вы можете попробовать взглянуть на любые фильтры, которые у вас есть на месте, а также.

Edit: некоторые более помощь в диагностике проблемы...

первый шаг к диагностике этой проблемы заключается в том, чтобы точно определить, где возникает исключение. Мы предполагаем, что он бросается линией

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

но вы можете обнаружить, что он выбрасывается позже в коде, где вы пытаетесь вывести в выходной поток после того, как вы попытались сделать форвард. Если он исходит из приведенной выше строки, то это означает, что где-то перед этой строкой у вас есть либо:

  1. вывод данных в выходной поток, или
  2. сделал еще один редирект заранее.

удачи!

Это потому, что ваш сервлет пытается получить доступ к объекту запроса, который больше не существует.. Оператор Forward или include сервлета не останавливает выполнение блока метода. Он продолжается до конца блока метода или первого оператора return, как и любой другой метод java.

лучший способ решить эту проблему просто установите страницу (где вы предполагаете переслать запрос) динамически в соответствии с вашей логикой. То есть:

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
}

и сделать вперед только один раз в последняя строка...

вы также можете исправить эту проблему, используя оператор return после каждого forward() или put each forward () в if...еще блок

Я убрал

        super.service(req, res);

тогда он отлично работал для меня

кочки...

у меня просто была такая же ошибка. Я заметил, что я вызываю super.doPost(request, response); при переопределении doPost() метод, а также явный вызов конструктора суперкласса

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

как только я закомментировал super.doPost(request, response); внутри doPost() заявление он работал отлично...

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

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

}

само собой разумеется, мне нужно перечитывать super() лучшие практики: p

вы должны добавить возвращение заявление во время пересылки или перенаправления потока.

пример:

Если forwardind,

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

Если перенаправления,

    response.sendRedirect(roundTripURI);
    return;

после возвращения метод, вы можете просто сделать это:

return null;

это нарушит текущую область.