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
提出的建议答案 0 :(得分:79)
首先,术语“重定向”是在Web开发世界中向客户端发送空HTTP响应的动作,其中只有一个Location
标题,其中包含客户端必须发送品牌的新URL新的GET请求。所以基本上:
somepage.xhtml
发送HTTP请求。Location: newpage.xhtml
标题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()
。