首先,术语“重定向”在 Web 开发世界中是指向客户端发送一个空的 HTTP 响应,其中只有一个Location
标头,其中包含客户端必须发送全新 GET 请求的新 URL。所以基本上:
- 客户端向
somepage.xhtml
.
- 服务器发回带有
Location: newpage.xhtml
标头的 HTTP 响应
- 客户端发送一个 HTTP 请求
newpage.xhtml
(这会反映在浏览器地址栏中!)
- 服务器发回 HTTP 响应,内容为
newpage.xhtml
.
您可以使用网络浏览器的内置/插件开发工具集对其进行跟踪。在 Chrome/IE9/Firebug 中按 F12 并检查“网络”部分以查看它。
JSF 导航处理程序不发送重定向。相反,它使用目标页面的内容作为 HTTP 响应。
- 客户端向
somepage.xhtml
.
- 服务器发回 HTTP 响应,内容为
newpage.xhtml
.
但是由于原始 HTTP 请求是 to somepage.xhtml
,所以浏览器地址栏中的 URL 保持不变。如果您熟悉基本的 Servlet API,那么您应该明白这与RequestDispatcher#forward()
.
HttpServletResponse
至于从 JSF 引擎盖下拉出并调用sendRedirect()
它是否正确使用;不,这不是正确的用法。你的服务器日志会被IllegalStateException
s 弄得乱七八糟,因为这样你就不会告诉 JSF 你已经接管了响应处理的控制权,因此 JSF 不应该做它的默认响应处理工作。您实际上应该在FacesContext#responseComplete()
之后执行。
此外,每当您需要从javax.servlet.*
JSF 工件(如托管 bean)中的包中导入某些内容时,您绝对应该停止编写代码并三思而后行,如果您真的以正确的方式做事,并问自己是否还没有“标准 JSF 方式”,无论您试图实现什么和/或该任务是否真的属于 JSF 托管 bean(即在某些情况下,一个简单的servlet 过滤器会是一个更好的地方)。
在 JSF 中执行重定向的正确方法是faces-redirect=true
在操作结果中使用查询字符串:
public String submit() {
// ...
return "/newpage.xhtml?faces-redirect=true";
}
或者ExternalContext#redirect()
当您不在诸如 ajax 或 prerender 侦听器方法之类的操作方法中时使用:
public void listener() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}
(是的,你不需要try-catch
在它周围加上a 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()
。
也可以看看: