我在处理 ajax 请求中的 ViewExpiredExceptions
时遇到问题。
在我的特殊情况下,它是一个会产生问题的 rich:datascroller
。我使用omnifaces 1.8.1 的FullAjaxExceptionHandler
来处理Ajax 组件抛出的VEE。
web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/my/pages/error/viewExpired.xhtml</location>
</error-page>
viewExpired.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:event type="preRenderView" listener="#{viewExpiredHandler.handle}" />
</html>
和 Java 类:
@Named
@RequestScoped
public class ViewExpiredHandler {
public void handle() {
String outcome = "/path/to/home.xhtml";
//Version 1 *************
try {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String redir = ec.getRequestContextPath() + outcome;
ec.redirect(redir);
} catch (IOException e) {
...
}
//Version 2 ************
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
fc.setViewRoot(fc.getApplication().getViewHandler().createView(fc, outcome));
fc.getPartialViewContext().setRenderAll(true);
fc.renderResponse();
}
}
如果 session 过期并且我单击 datascroller 按钮,我会看到我的 handle() 方法被调用,但转发到主页不起作用。
在版本 1 中,什么也没有发生,在版本 2 中,我首先得到一个空白屏幕,如果我使用浏览器按钮刷新页面,handle() 方法将再次被调用并成功重定向到主页
你能看到我的代码中有什么错误吗?
最佳答案
重定向无效,因为 FullAjaxExceptionHandler
完全接管渲染,因此 JSF 无法将 ajax 重定向写入响应。更改 View 没有任何效果,因为此时 FullAjaxExceptionHandler
已经掌握了错误页面 View ,并且不会查阅 FacesContext
来获取已更改的 View 。您会看到一个空白屏幕,因为您的错误页面本身是空白的。
让浏览器自行重定向即可。使用 JS window.location
。将整个 viewExpired.xhtml
页面替换为以下内容:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<script>window.location="#{request.contextPath}/path/to/home.xhtml";</script>
</body>
</html>
关于jsf-2 - ajax 请求中抛出 ViewExpiredException 时重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25082153/