重定向和导航/前进之间有什么区别以及何时使用什么?

时间:2012-06-30 20:19:04

标签: redirect jsf-2 navigation forward

JSF中的导航有什么区别

FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);

和重定向

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);

以及如何决定何时使用什么?

导航问题是除非faces-redirect=true添加到导航网址的查询字符串中,否则页面网址不会更改。但是,在我的情况下,如果我想重定向到像纯HTML页面这样的非JSF页面,则附加faces-redirect=true会抛出错误。

另一种选择是BalusC在JSF 2.0 redirect error

提出的建议

1 个答案:

答案 0 :(得分:79)

首先,术语“重定向”是在Web开发世界中向客户端发送空HTTP响应的动作,其中只有一个Location标题,其中包含客户端必须发送品牌的新URL新的GET请求。所以基本上:

  • 客户端向somepage.xhtml发送HTTP请求。
  • 服务器使用Location: newpage.xhtml标题
  • 发回HTTP响应
  • 客户端向newpage.xhtml发送HTTP请求(这反映在浏览器地址栏中!)
  • 服务器发回内容为newpage.xhtml的HTTP响应。

您可以使用webbrowser的内置/插件开发人员工具集进行跟踪。在Chrome / IE9 / Firebug中按F12,然后选中“网络”部分进行查看。

JSF navigationhandler不发送重定向。相反,它使用目标页面的内容作为HTTP响应。

  • 客户端向somepage.xhtml发送HTTP请求。
  • 服务器发回内容为newpage.xhtml的HTTP响应。

但是,由于原始HTTP请求是somepage.xhtml,因此浏览器地址栏中的URL保持不变。如果您熟悉basic Servlet API,那么您应该了解这与RequestDispatcher#forward()具有相同的效果。


关于是否从JSF引擎盖下拉HttpServletResponse并在其上调用sendRedirect()是正确的用法;不,这不是正确的用法。您的服务器日志将被IllegalStateException混乱,因为这样您就不会告诉JSF您已经接管了响应处理的控制权,因此JSF不应该执行其默认响应处理作业。事实上你应该事后执行FacesContext#responseComplete()

此外,每当您需要在像托管bean这样的JSF工件中导入javax.servlet.*包中的内容时,您绝对应该停止编写代码,如果您真的以正确的方式做事并且问自己,请三思而后行如果你想要实现的任何东西都没有“标准JSF方式”和/或任务真的属于JSF托管bean(有些情况下会出现一个简单的servlet filter一个更好的地方)。

在JSF中执行重定向的正确方法是在操作结果中使用faces-redirect=true查询字符串:

public String submit() {
    // ...
    return "/newpage.xhtml?faces-redirect=true";
}

当您不在ajax或prerender侦听器方法等操作方法中时使用ExternalContext#redirect()

public void listener() throws IOException {
    // ...
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}

(是的,您不需要在try-catch上放置IOException,只需让异常通过throws,servletcontainer将处理它)

或者在特定情况下使用NavigationHandler#handleNavigation()如果您正在使用XML导航案例和/或带有内置侦听器的自定义导航处理程序:

public void listener() {
    // ...
    FacesContext fc = FacesContext.getCurrentInstance();
    NavigationHandler nh = fc.getApplication().getNavigationHandler();
    nh.handleNavigation(fc, null, "/newpage.xhtml?faces-redirect=true");
}

为什么导航处理程序对“普通HTML”文件失败,这仅仅是因为导航处理程序只能处理JSF视图,而不能处理其他文件。您应该使用ExternalContext#redirect()

另见: