En Java Servlets, se puede acceder al cuerpo de la respuesta a través de response.getOutputStream()
o response.getWriter()
. ¿Debería recurrirse .close()
a esto OutputStream
después de que se haya escrito?
Por un lado, está la exhortación blochiana a cerrar siempre OutputStream
. Por otro lado, no creo que en este caso haya un recurso subyacente que deba cerrarse. La apertura / cierre de sockets se gestiona a nivel HTTP, para permitir cosas como conexiones persistentes y demás.
java
servlets
outputstream
Steven Huwig
fuente
fuente
close()
que no hace nada. Lo que debe hacer es cerrar todos los recursos que se puedan cerrar.Respuestas:
Normalmente no deberías cerrar la corriente. El contenedor de servlets cerrará automáticamente la secuencia después de que el servlet termine de ejecutarse como parte del ciclo de vida de la solicitud del servlet.
Por ejemplo, si cerrara la transmisión, no estaría disponible si implementara un Filtro .
Habiendo dicho todo eso, si lo cierras, no sucederá nada malo mientras no intentes volver a usarlo.
EDITAR: otro enlace de filtro
EDIT2: adrian.tarau tiene razón en que si desea alterar la respuesta después de que el servlet haya hecho su trabajo, debe crear un contenedor que extienda HttpServletResponseWrapper y almacenar en búfer la salida. Esto es para evitar que la salida vaya directamente al cliente, pero también le permite proteger si el servlet cierra la transmisión, según este extracto (el énfasis es mío):
Artículo
Se puede inferir de ese artículo oficial de Sun que cerrar el
OutputStream
desde un servlet es algo que ocurre normalmente, pero no es obligatorio.fuente
La regla general de ellos es la siguiente: si abrió la secuencia, debe cerrarla. Si no lo hizo, no debería. Asegúrate de que el código sea simétrico.
En el caso de
HttpServletResponse
, es un poco menos claro, ya que no es obvio si llamargetOutputStream()
es una operación que abre el flujo. El Javadoc simplemente dice que "Returns a ServletOutputStream
"; de manera similar paragetWriter()
. De cualquier manera, lo que está claro es queHttpServletResponse
"es dueño" de la secuencia / escritor, y él (o el contenedor) es responsable de cerrarlo nuevamente.Entonces, para responder a su pregunta, no, no debe cerrar la transmisión en este caso. El contenedor debe hacer eso, y si ingresa antes, corre el riesgo de introducir errores sutiles en su aplicación.
fuente
close()
cuando terminé con la secuencia, el cliente regresa inmediatamente y el resto del servlet continúa ejecutándose. ¿No hace eso que la respuesta sea un poco más relativa? en lugar de un sí o no definitivoSi existe alguna posibilidad de que se pueda llamar al filtro en un recurso 'incluido', definitivamente no debe cerrar la transmisión. Esto hará que el recurso incluido falle con una excepción de "secuencia cerrada".
fuente
Debe cerrar la secuencia, el código es más limpio ya que invoca getOutputStream () y la secuencia no se le pasa como parámetro, cuando normalmente solo lo usa y no intenta cerrarlo. La API de Servlet no establece que si el flujo de salida puede cerrarse o no debe cerrarse, en este caso puede cerrar el flujo de manera segura, cualquier contenedor se encarga de cerrar el flujo si el servlet no lo cerró.
Aquí está el método close () en Jetty, cierran la secuencia si no se cierra.
Además, como desarrollador de un filtro, no debe suponer que OutputStream no está cerrado, siempre debe pasar otro OutputStream si desea alterar el contenido después de que el servlet haya hecho su trabajo.
EDITAR: Siempre estoy cerrando la transmisión y no tuve ningún problema con Tomcat / Jetty. No creo que debas tener problemas con ningún contenedor, antiguo o nuevo.
fuente
Otro argumento en contra de cerrar el
OutputStream
. Mira este servlet. Lanza una excepción. La excepción se asigna en web.xml a un JSP de error:El archivo web.xml contiene:
Y el error.jsp:
Cuando carga
/Erroneous
en el navegador, ve la página de error que muestra "Un error". Pero si anula el comentario de laout.close()
línea en el servlet anterior, vuelve a implementar la aplicación y vuelve/Erroneous
a cargar , no verá nada en el navegador. No tengo ni idea de lo que está pasando realmente, pero supongo queout.close()
evita el manejo de errores.Probado con Tomcat 7.0.50, Java EE 6 usando Netbeans 7.4.
fuente