Redirect 重定向和导航/转发之间有什么区别?何时使用?
JSF中的导航有什么区别Redirect 重定向和导航/转发之间有什么区别?何时使用?,redirect,jsf-2,navigation,forward,Redirect,Jsf 2,Navigation,Forward,JSF中的导航有什么区别 FacesContext context = FacesContext.getCurrentInstance(); context.getApplication().getNavigationHandler().handleNavigation(context, null, url); 和重定向 HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);
和重定向
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);
以及如何决定何时使用什么
导航的问题是页面URL不会更改,除非将faces redirect=true
添加到导航URL的查询字符串中。然而,在我的例子中,如果我想重定向到非JSF页面(如普通HTML页面),则追加faces redirect=true
会引发错误
另一种选择是,正如BalusC在中所建议的,首先,术语“重定向”在web开发世界中是指向客户端发送一个空HTTP响应,其中只有一个位置
头,其中包含客户端必须发送全新GET请求的新URL。所以基本上:
- 客户端向
发送HTTP请求somepage.xhtml
- 服务器用
头返回HTTP响应位置:newpage.xhtml
- 客户端向
发送HTTP请求(这会反映在浏览器地址栏中!)newpage.xhtml
- 服务器返回一个HTTP响应,内容为
newpage.xhtml
- 客户端向
发送HTTP请求somepage.xhtml
- 服务器返回一个HTTP响应,内容为
newpage.xhtml
somepage.xhtml
,浏览器地址栏中的URL保持不变。如果您熟悉,那么您应该了解这与
从JSF引擎罩下拉出
HttpServletResponse
并在其上调用sendRedirect()
是否正确使用;不,那不是正确的用法。您的服务器日志将被IllegalStateException
s弄得乱七八糟,因为这样您就不会告诉JSF您已经接管了响应处理的控制权,因此JSF不应该执行其默认的响应处理工作。事实上,你应该在事后执行
此外,每当您需要从JSF工件(如托管bean)中的javax.servlet.*
package导入某些内容时,您都应该完全停止编写代码,并仔细考虑是否确实以正确的方式进行了操作,并问问自己是否已经有了“标准JSF方式”对于您试图实现的任何目标和/或任务是否真正属于JSF管理的bean(也就是说,在某些情况下,简单应用程序可能是更好的地方)
在JSF中执行重定向的正确方法是在操作结果中使用faces redirect=true
查询字符串:
public String submit() {
// ...
return "/newpage.xhtml?faces-redirect=true";
}
或者在不在操作方法(如ajax或prerender侦听器方法)内时使用:
public void listener() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}
(是的,您不需要在IOException
上的周围放置try catch
,只要让异常通过throws
,servletcontainer就会处理它)
或者在特定情况下使用,如果您使用的是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()
另见:
Flash#setKeepMessages()
将所有FacesMessage
s保留在Flash范围内。谢谢BalusC,您刚刚让我免于被Ajax自杀。几个月来,我一直在为两个不同的项目与联合国作出反应。当JSF启动新页面时,它们的所有事件都被预先使用,除非随机选择的命令按钮使ajax=“false”大量分散。在重新阅读了您对这篇文章的回复后,我突然想到尝试使用re direct清除JSF中的表单工作区。它在页面和支持bean操作中都发挥了绝对的作用。缺点是我现在必须重新访问我的所有代码。我认为这里有一个输入错误:“客户端向somepage.xhtml发送一个HTTP请求。服务器用newpage.xhtml的内容发送一个HTTP响应。”您向“somepage.xhtml”发送了请求,但得到了“newpage.xhtml”的内容,对吗?或者我遗漏了什么=?@Muntaser:不,没有输入错误。语句“您向”somepage.xhtml“发送了请求,但得到了”newpage.xhtml“的内容是正确的。如果您仍然不理解它,请后退一步,在深入研究JSF之前先学习基本的servlet。