Agregar Cookie después de FilterChain.doFilter() - ¿HttpServletResponseWrapper para ignorar el lavado?

Me gustaría agregar una cookie a un HttpServletResponse después de que su contenido (normalmente HTML) se haya renderizado.

Como se menciona aquí (http://osdir.com/ml/java.jasig.uportal/2005-10/msg00276.html), y aquí (¿Agregar una cookie a la respuesta en Java después de que se haya vaciado el encabezado?), esto es posible almacenando en búfer la respuesta para que no se vacíe y se envíe al cliente (ya que después de enviar los encabezados al cliente, la respuesta se confirma y no se pueden enviar más encabezados, es decir, encabezados de cookies, al cliente).

Suponiendo que este es el objetivo en cuestión: Entiendo que una forma posible de lograr esto es mediante el uso de un HttpServletResponseWrapper, puedo anular su flushBuffer() método y evitar el vaciado real de encabezados\contenido al cliente:

public class BufferedHttpServletResponse extends HttpServletResponseWrapper {

    public BufferedHttpServletResponse(HttpServletResponse response) {
        super(response);
    }

    public void flushBuffer() {
    }

}

y aplicar esta respuesta amortiguada en un Filter, para que el resto de la cadena de filtros utilice:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(response);

    chain.doFilter(request, bufferedResponse);

    // ... create Cookie and add it to response ... response.addCookie(newCookie)
    // response.flushBuffer() ?        

}

Pregunta: ¿Está bien lo anterior o está completamente apagado? ¿Seguirá llenándose el búfer de la respuesta con contenido\encabezados (y posiblemente cambiando de tamaño) hasta después de mi doFilter() salidas, para luego ser vaciadas y enviadas al cliente por otros filtros o por el contenedor de servlet (Tomcat)? ¿Debo vaciar la respuesta yo mismo? ... mencionado aquí (¿Se debe llamar a .close () en HttpServletResponse.getOutputStream () /. GetWriter ()?) ese flujo no debe cerrarse, pero ¿debería vaciarse la respuesta en este caso?

No necesariamente asumiendo que este es el objetivo en cuestión: Mi problema general es que necesito configurar una cookie para el navegador de un cliente, pero el valor de la cookie depende de las cosas que suceden mientras se representa el contenido de la respuesta (cosas que suceden en una acción de Struts 1.0 y luego en una plantilla de Velocity) - Sé qué valor de cookie quiero establecer solo después de pasar por todo el flujo (Servlet -> Representación de HTML).

Ilumíname por favor. Gracias.

preguntado el 28 de agosto de 12 a las 09:08

1 Respuestas

Parece que nadie está listo para tomar esto, intentaré proporcionar al menos mi punto de vista.

Antes de llegar a su pregunta Primero, veamos las tareas principales del filtro de servlet.

  • Consultar la solicitud y actuar en consecuencia.
  • Bloquear el par de solicitud y respuesta para que no pase más.
  • Modifique los encabezados y datos de la solicitud. Para ello, proporcione una versión personalizada de la solicitud.
  • Modifique los encabezados y los datos de la respuesta. Para ello, proporcione una versión personalizada de la respuesta.

Fuente: http://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html

Volviendo a su pregunta ahora, puede modificar los encabezados de respuesta personalizando la respuesta también conocida como ResponseWrapper.

Mirando su código, lo que está tratando de hacer es modificar la respuesta original en lugar de modificar la respuesta personalizada y cuál (agregar una cookie a la respuesta original) es no está bien.

Entonces, la forma correcta de hacerlo es agregar la cookie en su personalizado, algo como el ejemplo a continuación.

   private class CustomResponseWrapper extends HttpServletResponseWrapper {

        private Collection<Cookie> myCookies = new ArrayList<Cookie>();

        public CustomResponseWrapper(HttpServletResponse response) {
            super(response);
        }

        @Override
        public void addCookie(Cookie cookie) {
            super.addCookie(cookie);
            myCookies.add(cookie);
        }
    }

Respondido 31 ago 12, 22:08

Gracias por los avisos, sin embargo, no estoy tratando de capturar las cookies creadas por el resto de la cadena de filtros, si ese es el pensamiento detrás del código anterior (fabrico una sola cookie después de la invocación .doChain() del filtro, y solo quiero asegurarme de que llegue al cliente). ¿Cómo puedo evitar que el resto de la cadena de filtros descargue \ cierre la respuesta para poder agregar la cookie? - globulo

también, estoy pensando que agregar la cookie a la respuesta original o a la respuesta de envoltura es lo mismo, ya que una llamada a .addCookie() de la respuesta de envoltura tiene como valor predeterminado llamar a través de .addCookie() de la respuesta original - globulo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.