Этот метод броски
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);
}
Распространенное заблуждение среди начинающих состоит в том, что они думают, что вызов 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?
Как правило, вы видите эту ошибку после того, как вы уже сделали перенаправление, а затем попробуйте выводить еще несколько данных в выходной поток. В тех случаях, когда я видел это в прошлом, часто одна из фильтров, которые пытаются перенаправить страницу, а затем все еще пересылают на сервлете. Я не вижу ничего сразу не так с сервлетом, поэтому вы можете попробовать взглянуть на любые фильтры, которые у вас есть на месте.
Редактировать : Еще одна помощь в диагностике проблемы ...
Первый шаг для диагностики этой проблемы состоит в том, чтобы точно определить, где выдается исключение. Предполагаем, что он брошен в строку
getServletConfig().getServletContext()
.getRequestDispatcher("/GroupCopiedUpdt.jsp")
.forward(request, response);
, но вы можете обнаружить, что он брошен позже в коде, где вы пытаетесь выводить в выходной поток после того, как вы пытались сделать вперед. Если он исходит с вышеуказанной линии, то это означает, что где-то до этой линии у вас есть либо:
Удачи!