java.lang. IllegalStateException: не Может (вперед | sendRedirect |, создают сессию) после того, как ответ фиксировался

Этот метод броски

java.lang. 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);
    }
90
задан BalusC 30 January 2017 в 08:45
поделиться

2 ответа

Распространенное заблуждение среди начинающих состоит в том, что они думают, что вызов 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.lang.IllegalStateException: невозможно переадресовать после того, как ответ был зафиксирован

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

java.lang.IllegalStateException: Невозможно вызвать sendRedirect () после того, как ответ был зафиксирован

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

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

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

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

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

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


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

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

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

java. lang.IllegalStateException: невозможно пересылать после того, как ответ был зафиксирован

Решение очевидно, просто не записывайте в ответ в сервлете. Это ответственность JSP. Вы просто устанавливаете атрибут запроса, например, request.setAttribute («данные», «некоторая строка») , а затем распечатываете его в JSP, например, так $ {data} . См. Также нашу вики-страницу о сервлетах , чтобы узнать, как правильно использовать сервлеты.


Еще одна вероятная причина заключается в том, что методы forward () , sendRedirect () или sendError () вызываются с помощью кода Java, встроенного в файл JSP. в форме старомодного способа <% scriptlets%> , практика, которая официально запрещалась с 2001 года . Например:

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

        <% sendRedirect(); %>

        ...
    </body>
</html>

Проблема в том, что JSP внутренне немедленно записывает текст шаблона (то есть код HTML) через out.write (" ... etc ...") , как только как он встречается. Таким образом, это, по сути, та же проблема, что объяснялась в предыдущем разделе.

Решение очевидно, просто не пишите код Java в файле JSP. Это ответственность обычного Java-класса, такого как сервлет или фильтр. См. Также нашу вики-страницу о сервлетах , чтобы узнать, как правильно использовать сервлеты.


См. Также:


Несвязанный с вашей конкретной проблемой, ваш код JDBC утекает ресурсы. Исправьте и это.Подсказки см. Также в Как часто следует закрывать Connection, Statement и ResultSet в JDBC?

237
ответ дан 24 November 2019 в 06:56
поделиться

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

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

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

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

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

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

Удачи!

6
ответ дан 24 November 2019 в 06:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: