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

ad-*_*inf 32 navigation redirect forward jsf-2

JSF中的导航有什么区别

FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);
Run Code Online (Sandbox Code Playgroud)

和重定向

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);
Run Code Online (Sandbox Code Playgroud)

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

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

另一种选择是BalusC在JSF 2.0重定向错误中提出的建议

Bal*_*usC 79

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

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

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

JSF导航处理程序不发送重定向.相反,它使用目标页面的内容作为HTTP响应.

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

但是,根据原始HTTP请求somepage.xhtml,浏览器地址栏中的URL保持不变.如果您熟悉基本的Servlet API,那么您应该理解它具有与之相同的效果RequestDispatcher#forward().


至于是否HttpServletResponse从JSF罩下拉动并调用sendRedirect()它是正确的用法; 不,这不是正确的用法.你的服务器日志会变得混乱,IllegalStateException因为这样你就不会告诉JSF你已经接管了响应处理的控制,因此JSF不应该做它的默认响应处理工作.事实上你应该FacesContext#responseComplete()事后执行.

此外,每当你需要javax.servlet.*在像托管bean这样的JSF工件中从包中导入东西时,你绝对应该停止编写代码,如果你真的以正确的方式做事并且问自己是否还没有"标准的JSF方式"无论你想要实现什么和/或任务是否真的属于JSF托管bean(有些情况下,简单的servlet过滤器会是一个更好的地方).

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

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

或者ExternalContext#redirect()在不在诸如ajax或prerender侦听器方法之类的操作方法中时使用:

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

(是的,你不需要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");
}
Run Code Online (Sandbox Code Playgroud)

至于导航处理程序为"普通HTML"文件失败的原因,这仅仅是因为导航处理程序只能处理JSF视图,而不能处理其他文件.那你应该用ExternalContext#redirect().

也可以看看:

  • 如果重定向位于同一路径上,那么您可以使用`Flash #setKeepMessages()`将所有`FacesMessage'保留在flash范围内. (2认同)