Ява.ленг.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 ответов:
распространенное недоразумение среди начинающих заключается в том, что они думают, что вызов
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
оператор вызывает aforward()
а ты потом звонишь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);
но вы можете обнаружить, что он выбрасывается позже в коде, где вы пытаетесь вывести в выходной поток после того, как вы попытались сделать форвард. Если он исходит из приведенной выше строки, то это означает, что где-то перед этой строкой у вас есть либо:
- вывод данных в выходной поток, или
- сделал еще один редирект заранее.
удачи!
Это потому, что ваш сервлет пытается получить доступ к объекту запроса, который больше не существует.. Оператор 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.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