Распространенным заблуждением среди начинающих является то, что они думают, что вызов 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("data", "some string")
, а затем печатаете его в JSP, например, ${data}
. См. Также нашу вики-страницу Servlets , чтобы узнать, как правильно использовать Servlets.
Смотри также:
Не связано с вашей конкретной проблемой, ваш код JDBC пропускает ресурсы. Исправьте это также. Подсказки см. Также Как часто должны быть закрыты Connection, Statement и ResultSet в JDBC?