2010-08-04 13 views
6

La lógica es que el filtro recibe un golpe, la condición no es verdadera, por lo que pasa por la cadena de filtro. Después de confirmar la respuesta, el filtro recibe un golpe, y la condición ahora es verdadera (se estableció un atributo de solicitud). Entra para ejecutar el reenvío, pero la página nunca avanza. Sé que esto tiene algo que ver con la respuesta que se está cometiendo porque probé una lógica diferente en la que avanza antes de que llegue a la cadena por primera vez, y avanza con éxito.¿Es posible reenviar o redireccionar desde un filtro de servlet después de que se haya confirmado la respuesta?

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 

    HttpServletRequest httpServletRequest = (HttpServletRequest)request; 

    if (some condition equals true) { 
     httpServletRequest.getRequestDispatcher("/home.jsp").forward(request, response); 
     return; 
    } else { 
     chain.doFilter(request, response); 
    } 
} 

ejemplo de mi descriptor de despliegue:

<filter> 
    <filter-name>MyFilter</filter-name> 
    <filter-class>com.filters.MyFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>MyFilter</filter-name> 
    <url-pattern>*.jsp</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping> 

Respuesta

14

El estado "comprometida" de un HttpServletResponse es realmente una forma de decir si las cabeceras de respuesta se han escrito en el conector subyacente. Una respuesta "comprometida" ha tenido (al menos) la primera línea escrita. Como la primera línea de la respuesta contiene el código de estado, se deduce que no puede cambiar el código de estado de una respuesta comprometida ... y eso significa que es demasiado tarde para cambiar el estado a 3xx para hacer una redirección. Del mismo modo, no puede hacer un reenvío local porque ya ha comenzado a enviar la respuesta.

4

Puede lograr lo que desea utilizando un HttpServletResponse personalizado. Pasa esta HttpServletResponse envuelta por la cadena de filtros. Puede proporcionar un OutputStream local que almacena todas las solicitudes de escritura, variables locales para almacenar el código de estado y los encabezados. Una vez que haya regresado a su filtro, puede decidir redirigir o copiar los resultados de las variables locales desde el contenedor al ServletResponse original (es decir, establecer el código de estado y el encabezado y copiar los resultados del flujo de salida local en el flujo de salida de respuesta servlet).

Editar:

Consulte la sección Programming Customized Requests and Responses para un ejemplo de código que utiliza un CharResponseWrapper. El ejemplo usa un Writer personalizado, pero se puede extender fácilmente a un OutputStream. En función de cómo se use su Servlet, debe anular uno o ambos getWriter() y getOutputStream() para retrasar el envío de cualquier cosa a la respuesta original. Además, deberá sobrescribir isCommitted() para devolver false, de modo que el reenvío se pueda ejecutar en cualquier momento en la cadena de filtros. También deberá sobrescribir resetBuffer() para inicializar un nuevo OutputStream/Writer para almacenar el nuevo contenido (incluidos los encabezados) después del redireccionamiento/reenvío.

+0

¿Podría proporcionar algún 'código de muestra' basado en el redireccionamiento'/home.jsp' deseado anteriormente? También estoy teniendo problemas con este problema. ¡Gracias! – DougA

+0

@DougA revisa las ediciones en mi respuesta. Eso debería resumir lo que se necesita hacer. – shams

Cuestiones relacionadas