servlets - java.lang.IllegalStateException: No se puede(reenviar | enviarRedirección | crear sesión) después de que se haya confirmado la respuesta
response forward (8)
Bache...
Acabo de tener el mismo error. Noté que estaba invocando a super.doPost(request, response);
al anular el método doPost()
e invocar explícitamente el constructor de la superclase
public ScheduleServlet() {
super();
// TODO Auto-generated constructor stub
}
Tan pronto como super.doPost(request, response);
el super.doPost(request, response);
desde dentro de la doPost()
funcionó perfectamente ...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//super.doPost(request, response);
// More code here...
}
No hace falta decir que necesito volver a leer sobre super()
mejores prácticas de super()
: p
Este método arroja
java.lang.IllegalStateException: no se puede reenviar después de que se haya confirmado la respuesta
y no puedo detectar el problema ¿Alguna ayuda?
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);
}
Debe agregar declaración de devolución mientras reenvía o redirige el flujo.
Ejemplo:
si forwardind,
request.getRequestDispatcher("/abs.jsp").forward(request, response);
return;
si redirige,
response.sendRedirect(roundTripURI);
return;
Después del método de devolución, simplemente puede hacer esto:
return null;
Romperá el alcance actual.
Esto se debe a que su servlet está intentando acceder a un objeto de solicitud que ya no existe. La instrucción de reenvío o inclusión de un servlet no detiene la ejecución del bloque de método. Continúa hasta el final del bloque de método o la declaración de primer retorno al igual que cualquier otro método de Java.
La mejor manera de resolver este problema es configurar la página (donde suponga que reenvía la solicitud) dinámicamente según su lógica. Es decir:
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
}
y hacer el reenvío una sola vez en la última línea ...
También puede solucionar este problema utilizando la declaración return después de cada forward () o poner cada forward () en el bloque if ... else
Normalmente verá este error después de que ya haya realizado una redirección y luego intente generar más datos en la secuencia de salida. En los casos en que he visto esto en el pasado, a menudo es uno de los filtros que intenta redireccionar la página y luego reenvía hacia el servlet. No puedo ver nada inmediatamente incorrecto con el servlet, por lo que es posible que desee intentar echar un vistazo a los filtros que tiene en su lugar también.
Editar : Un poco más de ayuda para diagnosticar el problema ...
El primer paso para diagnosticar este problema es determinar exactamente dónde se lanza la excepción. Estamos asumiendo que está siendo arrojado por la línea
getServletConfig().getServletContext()
.getRequestDispatcher("/GroupCopiedUpdt.jsp")
.forward(request, response);
Pero es posible que descubra que se lanzará más adelante en el código, donde está tratando de enviar a la secuencia de salida después de haber intentado hacer el reenvío. Si proviene de la línea anterior, significa que en algún lugar antes de esta línea tienes:
- datos de salida a la secuencia de salida, o
- hecho otra redirección de antemano.
¡Buena suerte!
Un malentendido común entre los principiantes es que piensan que la llamada de un forward()
, sendRedirect()
o sendError()
mágicamente sendError()
y "saltará" del bloque de método, ignorando así el resto del código. Por ejemplo:
protected void doPost() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!
}
Esto no es verdad. Ciertamente, no se comportan de manera diferente que cualquier otro método de Java System#exit()
por supuesto, System#exit()
). Cuando el ejemplo de someCondition
en el ejemplo anterior es true
y usted está llamando forward()
después de sendRedirect()
o sendError()
en la misma solicitud / respuesta, entonces existe la posibilidad de que obtenga la excepción:
java.lang.IllegalStateException: no se puede reenviar después de que se haya confirmado la respuesta
Si la instrucción if
llama a forward()
y luego llama a sendRedirect()
o sendError()
, se generará la siguiente excepción:
java.lang.IllegalStateException: no se puede llamar a sendRedirect () después de que se haya confirmado la respuesta
Para solucionar esto, necesita agregar una return;
declaración después
protected void doPost() {
if (someCondition) {
sendRedirect();
return;
}
forward();
}
... o para introducir un bloque else.
protected void doPost() {
if (someCondition) {
sendRedirect();
} else {
forward();
}
}
Para eliminar la raíz del código, simplemente busque cualquier línea que invoque forward()
, sendRedirect()
o sendError()
sin salir del bloque de métodos u omitiendo el resto del código. Esto puede estar dentro del mismo servlet antes de la línea de código particular, pero también en cualquier servlet o filtro que haya sido llamado antes del servlet particular.
En el caso de sendError()
, si su único propósito es establecer el estado de la respuesta, use setStatus()
lugar.
Otra causa probable es que el servlet escribe en la respuesta mientras se llamará a un forward()
, o ha sido llamado en el mismo método.
protected void doPost() {
out.write("some string");
// ...
forward(); // Fail!
}
El tamaño del búfer de respuesta se predetermina en la mayoría del servidor a 2 KB, por lo que si escribe más de 2 KB en él, se confirmará y forward()
fallará de la misma manera:
java.lang.IllegalStateException: no se puede reenviar después de que se haya confirmado la respuesta
La solución es obvia, simplemente no escriba en la respuesta en el servlet. Esa es la responsabilidad del JSP. Simplemente establece un atributo de solicitud como request.setAttribute("data", "some string")
y luego imprímalo en JSP como ${data}
. Consulte también nuestra página wiki Servlets para aprender a usar Servlets de la manera correcta.
Ver también:
Sin relación con su problema concreto, su código JDBC está perdiendo recursos. Arregle eso también. Para obtener sugerencias, consulte también ¿Con qué frecuencia se deben cerrar Connection, Statement y ResultSet en JDBC?
incluso al agregar una declaración de retorno aparece esta excepción, para la cual la única solución es este código:
if(!response.isCommitted())
// Place another redirection
quite
super.service(req, res);
Entonces funcionó bien para mí