2011-10-20 7 views
6

Tengo una pregunta sobre la navegación de las caras.caras redirige y el botón Atrás hace que otros enlaces funcionen incorrectamente

Así que tengo una página que toma un parámetro de solicitud para cargar un usuario específico. Esta página muestra una lista de commandLink que, cuando se hace clic en ella, redirige a otra página usando navegación implícita. El usuario se carga llamando a un método en "preRenderView".

La página a la que redirigimos también toma un parámetro de solicitud para determinar qué caso cargar. La página también está utilizando preRenderView.

Ambas páginas tienen beans que se ven en el ámbito.

Todo esto funciona increíble para el primer enlace que se presiona. La primera página redirige a la nueva URL y el caso se carga como se esperaba.

SIN EMBARGO, si hago clic en el botón Atrás del navegador y luego hago clic en otro enlace, la página NO redirige. Se actualiza (en cambio) y, obviamente, no compra el caso.

Después de la actualización, puedo hacer clic en un enlace y se redireccionará correctamente.

Ahora, todo esto funciona totalmente bien cuando el bean de la primera página se mantiene en la sesión, pero no quiero abusar del estado de la sesión y no creo que deba ser necesario para mantener estos datos en La sesión.

Sé que puedo solucionar esto haciendo que la página se vuelva a cargar automáticamente cuando haga clic en el botón Atrás (porque la vista se volverá a crear) pero no estoy seguro de si esa es la solución correcta. (Tampoco estoy seguro de cómo forzaría esto)

¿Alguien tiene alguna sugerencia? Parece un caso de uso bastante común, pero no pude encontrar ningún ejemplo.

Gracias!

Respuesta

11

Básicamente, debe indicar al navegador que no almacene en caché las páginas JSF generadas dinámicamente mientras tiene el método de ahorro de estado de vista establecido en (predeterminado) server. El estado de vista se rastrea mediante un campo <input type="hidden" name="javax.faces.ViewState"> en forma de la página JSF generada con el identificador de estado de vista como valor de entrada. Cuando envía una página y navega a una página diferente, el estado de la vista se descarta en el servidor y ya no existe. Recuperar la página de la memoria caché del navegador aún le daría ese viejo identificador de estado de vista como valor de la entrada oculta. Enviar ese formulario no funcionará en absoluto, ya que no se puede encontrar ningún estado de vista en el servidor.

Desea obtener una nueva página nueva directamente desde el servidor en lugar de desde el caché del navegador. Con el fin de decirle al navegador para hacer eso, crear un Filter así:

@WebFilter(servletNames={"Faces Servlet"}) 
public class NoCacheFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest httpReq = (HttpServletRequest) request; 
     HttpServletResponse httpRes = (HttpServletResponse) response; 

     if (!httpReq.getRequestURI().startsWith(httpReq.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc) 
      httpRes.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
      httpRes.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
      httpRes.setDateHeader("Expires", 0); // Proxies. 
     } 

     chain.doFilter(request, response); 
    } 

    // ... 
} 

De esta manera el botón de retroceso enviará una petición HTTP fullworthy que debe volver a crear el estado de vista y dar lugar a una página con un formulario con el la vista correcta indica el valor del campo oculto.

+5

Balus, eres un dios. Gracias. – jjross

Cuestiones relacionadas