redirect - quiénes - que qué diferencia
¿Cuál es la diferencia entre redirigir y navegación/reenviar y cuándo usar qué? (1)
En primer lugar, el término "redirigir" es en el mundo del desarrollo web la acción de enviar al cliente una respuesta HTTP vacía con solo un encabezado de Location
con la nueva URL en la que el cliente debe enviar una nueva solicitud GET. Así que básicamente:
- El cliente envía una solicitud HTTP a
somepage.xhtml
. - El servidor envía una respuesta HTTP con
Location: newpage.xhtml
header - El cliente envía una solicitud HTTP a
newpage.xhtml
(¡esto se refleja en la barra de direcciones del navegador!) - El servidor envía una respuesta HTTP con contenido de
newpage.xhtml
.
Puede rastrearlo con el conjunto de herramientas desarrollador / complemento de webbrowser. Presione F12 en Chrome / IE9 / Firebug y revise la sección "Red" para verla.
El manejador de navegación JSF no envía un redireccionamiento. En cambio, usa el contenido de la página de destino como respuesta HTTP.
- El cliente envía una solicitud HTTP a
somepage.xhtml
. - El servidor envía una respuesta HTTP con contenido de
newpage.xhtml
.
Sin embargo, como la solicitud HTTP original era para somepage.xhtml
, la URL en la barra de direcciones del navegador permanece sin cambios. Si está familiarizado con la API de Servlet básica , debe comprender que esto tiene el mismo efecto que RequestDispatcher#forward()
.
En cuanto a si tirando de HttpServletResponse
desde debajo de los capós JSF y llamando a sendRedirect()
en él es el uso correcto; no, ese no es el uso correcto. Los registros de su servidor se IllegalStateException
porque de esta manera no le está diciendo a JSF que ya asumió el control del manejo de la respuesta y, por lo tanto, JSF no debería realizar su trabajo de manejo de respuesta predeterminado. De hecho, FacesContext#responseComplete()
ejecutar FacesContext#responseComplete()
luego.
Además, cada vez que necesite importar algo del paquete javax.servlet.*
En un artefacto JSF como un frijol administrado, debe dejar de escribir código y pensar dos veces si realmente está haciendo las cosas correctamente y preguntarse si no hay Ya no es una "forma estándar de JSF" para lo que está tratando de lograr y / o si la tarea realmente pertenece a un bean administrado JSF (hay algunos casos en los que un filtro de servlet simple habría sido un mejor lugar).
La forma correcta de realizar una redirección en JSF es usar faces-redirect=true
cadena de consulta faces-redirect=true
en el resultado de la acción:
public String submit() {
// ...
return "/newpage.xhtml?faces-redirect=true";
}
O usando ExternalContext#redirect()
cuando no está dentro de un método de acción como ajax o prerender método de escucha:
public void listener() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}
(Sí, no es necesario que try-catch
en IOException
, solo deje que la excepción pase por throws
, servletcontainer lo manejará)
O usando NavigationHandler#handleNavigation()
en casos específicos si está utilizando casos de navegación XML y / o un controlador de navegación personalizado con algún oyente incorporado:
public void listener() {
// ...
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, "/newpage.xhtml?faces-redirect=true");
}
En cuanto a por qué el controlador de navegación falla para los archivos "HTML sin formato", es simplemente porque el controlador de navegación solo puede procesar vistas JSF, no otros archivos. Debería utilizar ExternalContext#redirect()
luego.
Ver también:
Cuál es la diferencia entre una navegación en JSF
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);
y una redirección
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);
y cómo decidir cuándo usar qué?
El problema con la navegación es que la URL de la página no cambia a menos que faces-redirect=true
se agregue a la cadena de consulta de la URL de navegación. Sin embargo, en mi caso se agrega faces-redirect=true
throws error si quiero redireccionar a una página que no sea JSF como una página HTML simple.
Y otra opción es como sugirió BalusC en el error de redirección de JSF 2.0