2012-02-29 14 views
6

He estado cavando por la web después de solucionar un problema esta tarde @ work donde las cookies añadidas a HttpServletResponse no se reflejaban correctamente en los encabezados de respuesta porque nuestro Servlet ya había recuperado el PrintWriter de la respuesta (es decir, response.getWriter()) antes de agregar las cookies. Ahora estoy al tanto de que las mejores prácticas dictan que las modificaciones del encabezado de respuesta (es decir, establecer el tipo de contenido, agregar/editar cookies, etc.) deben hacerse antes de una llamada a getWriter() pero, lo que estoy buscando es: ¿por qué?¿Por qué no se pueden actualizar los encabezados HttpServletResponse DESPUÉS de llamar a getWriter()?

Hemos estado especulando acerca de por qué recuperar el PrintWriter congela los encabezados de respuesta, pero ¿por qué definitivamente la especificación de Servlet hace cumplir eso?

Respuesta

11

Sección encabezados SRV.5.2 del Java ™ Servlet Specification Version 2,4

Para transmitir correctamente al cliente, los encabezados se deben establecer antes está comprometida la respuesta. Los encabezados configurados después de confirmar la respuesta serán ignorados por el contenedor de servlet.

Por lo tanto, la especificación no menciona explícitamente getWriter() teniendo un efecto en la configuración de los encabezados.

Sin embargo, la implementación de su contenedor de servlet puede haber elegido tratar la respuesta como si se hubiera recibido una vez que se llama getWriter(). Eso es sutilmente diferente.

En algunos de los contenedores con los que he trabajado, aparece un mensaje de advertencia cuando intenta establecer un encabezado después de que se haya realizado la respuesta.

Siempre vale la pena llamar al getWriter() lo más tarde posible, ya que es posible que desee la oportunidad de establecer la codificación de caracteres, etc., que se debe configurar antes de llamar al getWriter().

+0

Gracias Paul! Eso tiene sentido. Entonces, es probable que Tomcat esté demasiado celoso acerca de cuándo considerar cerrar los encabezados para modificarlos. Mi error fue suponer que los datos que escribimos al cuerpo de la respuesta antes de llamar a out.flush() no estaban esencialmente comprometidos, pero probablemente ese no sea el caso. ¡Gracias de nuevo! –

+0

Hermosa respuesta y buena referencia. Gracias Paul. –

3

Porque los encabezados preceden al cuerpo en HTTP. Es por eso que se llaman 'encabezados'. Si llama a getWriter(), está escribiendo en el cuerpo, por lo que después es demasiado tarde para comenzar a cambiar los valores del encabezado de respuesta.

Cuestiones relacionadas