Этот метод бросает
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);
}
Ответы:
Распространенное заблуждение среди начинающих состоит в том, что они думают, что вызов a
forward()
,sendRedirect()
илиsendError()
мог бы волшебным образом выйти и «выпрыгнуть» из блока метода, таким образом игнорируя остаток кода. Например:Таким образом, на самом деле это не так. Они определенно не ведут себя иначе, чем любые другие методы Java (за исключением,
System#exit()
конечно). КогдаsomeCondition
в приведенном выше примереtrue
вы вызываетеforward()
послеsendRedirect()
илиsendError()
по одному и тому же запросу / ответу, тогда велика вероятность того, что вы получите исключение:Если
if
оператор вызывает a,forward()
а затем вы вызываетеsendRedirect()
илиsendError()
, будет выбрано следующее исключение:Чтобы исправить это, вам нужно либо добавить
return;
оператор позже... или ввести блок else.
Чтобы выявить основную причину в вашем коде, просто найдите любую строку, которая вызывает a
forward()
,sendRedirect()
илиsendError()
не выходя из блока метода или пропуская остаток кода. Это может быть внутри того же сервлета перед конкретной строкой кода, но также и в любом сервлете или фильтре, который был вызван перед определенным сервлетом.В случае
sendError()
, если ваша единственная цель - установить статус ответа, используйтеsetStatus()
вместо этого.Другая вероятная причина заключается в том, что сервлет записывает в ответ, пока
forward()
будет вызван, или был вызван тем же методом.Размер буфера ответа по умолчанию на большинстве серверов равен 2 КБ, поэтому, если вы напишете в него более 2 КБ, он будет зафиксирован и
forward()
завершится ошибкой таким же образом:Решение очевидное, только не пишите в ответ в сервлете. Это ответственность JSP. Вы просто устанавливаете атрибут запроса таким образом,
request.setAttribute("data", "some string")
а затем распечатываете его в JSP вот так${data}
. См. Также нашу вики-страницу о сервлетах, чтобы узнать, как правильно использовать сервлеты.Другой вероятной причиной является то, что сервлет записывает загрузку файла в ответ, после чего, например,
forward()
вызывается a .Это технически невозможно. Вам нужно удалить
forward()
звонок. Конечный пользователь останется на текущей открытой странице. Если вы действительно намереваетесь изменить страницу после загрузки файла, вам необходимо переместить логику загрузки файла на загрузку целевой страницы.Еще одна вероятная причина заключается в том
forward()
, что методы ,sendRedirect()
илиsendError()
вызываются через Java-код, встроенный в файл JSP, в форме старомодного способа<% scriptlets %>
, практика, которая официально не поощрялась с 2001 года . Например:Проблема здесь в том, что JSP внутренне немедленно записывает текст шаблона (то есть код HTML),
out.write("<!DOCTYPE html> ... etc ...")
как только он встречается. Таким образом, это, по сути, та же проблема, что объяснялась в предыдущем разделе.Решение очевидно, просто не пишите Java-код в JSP-файле. Это ответственность обычного Java-класса, такого как сервлет или фильтр. См. Также нашу вики-страницу о сервлетах, чтобы узнать, как правильно использовать сервлеты.
Смотрите также:
Не связанный с вашей конкретной проблемой, ваш JDBC-код теряет ресурсы. Исправьте и это. Подсказки см. Также в разделе Как часто следует закрывать Connection, Statement и ResultSet в JDBC?
источник
break;
? Это означало бы, что код был внутри некоторого циклаfor
или, вwhile
которомforward()
он неоднократно вызывался во время цикла (что, таким образом, неверно, вы должны вызывать переадресацию только один раз ПОСЛЕ цикла - или чтобы избавиться от цикла, поскольку он, по-видимому, не нужен) .forward()
вызов, хотя этого делать не должно. JSF, с которым я знаком, делает это также, если вы явно не вызываетеFacesContext#responseComplete()
. Этот связанный вопрос (который я нашел с помощью ключевых слов «grails предотвращает ответ на рендеринг») может быть полезен: stackoverflow.com/questions/5708654/…forward()
вызов, хотя этого делать не должно. Решение функционально очевидно: скажите ему, чтобы он этого не делал. Он понятия не имел, что вы программно взяли на себя работу, которую должен был выполнять Grails: обработку ответа. Технически, я понятия не имею, как сказать об этом Grails. Но я знаю, что это поддерживают многие другие фреймворки MVC (которым даны инструкции не обрабатывать ответ сам по себе), например JSF, Spring MVC, Wicket и т. Д. Я был бы удивлен, если это невозможно в Grails.даже добавление оператора return вызывает это исключение, единственным решением для которого является следующий код:
источник
Обычно эта ошибка появляется после того, как вы уже выполнили перенаправление, а затем пытаетесь вывести дополнительные данные в выходной поток. В тех случаях, когда я видел это в прошлом, часто один из фильтров пытается перенаправить страницу, а затем все еще перенаправляет ее на сервлет. Я не могу сразу увидеть что-то неправильное с сервлетом, поэтому вы можете попробовать взглянуть на любые фильтры, которые у вас есть.
Изменить : еще немного помощи в диагностике проблемы ...
Первым шагом к диагностике этой проблемы является точное определение места возникновения исключения. Мы предполагаем, что его выбрасывает линия
Но вы можете обнаружить, что он выбрасывается позже в коде, где вы пытаетесь вывести в выходной поток после того, как попытались выполнить пересылку. Если он исходит из вышеприведенной строки, это означает, что где-то перед этой строкой у вас есть:
Удачи!
источник
Это связано с тем, что ваш сервлет пытается получить доступ к объекту запроса, которого больше не существует. Оператор forward или include сервлета не останавливает выполнение блока метода. Он продолжается до конца блока метода или первого оператора возврата, как и любой другой метод Java.
Лучший способ решить эту проблему - просто настроить страницу (на которую вы предполагаете перенаправить запрос) динамически в соответствии с вашей логикой. То есть:
и проделайте только один раз в последней строке ...
вы также можете решить эту проблему, используя оператор return после каждого forward () или помещая каждый forward () в блок if ... else
источник
Я удалил
Тогда это сработало для меня
источник
Удар...
У меня была такая же ошибка. Я заметил, что вызываю
super.doPost(request, response);
при переопределенииdoPost()
метода, а также явно вызываю конструктор суперклассаКак только я закомментировал заявление
super.doPost(request, response);
изнутри,doPost()
оно сработало отлично ...Излишне говорить, что мне нужно перечитать
super()
передовой опыт: pисточник
Вы должны добавить оператор return во время пересылки или перенаправления потока.
Пример:
если переадресация,
при перенаправлении,
источник
После метода возврата вперед вы можете просто сделать это:
Это нарушит текущий объем.
источник