在ajax请求中抛出ViewExpiredException时重定向

时间:2014-08-01 14:09:39

标签: jsf-2 richfaces omnifaces

我在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();
        }
}

如果会话过期并且我点击了一个datascroller按钮,我会看到我的handle()方法被调用,但转发到主页并不起作用。

版本1根本没有任何反应,版本2我首先得到一个空白屏幕,如果我用浏览器按钮刷新页面,则会再次调用handle()方法并成功重定向到主页

你能在我的代码中看到任何错误吗?

1 个答案:

答案 0 :(得分:4)

重定向无效,因为FullAjaxExceptionHandler完全接管渲染,因此JSF无法将ajax重定向写入响应。更改视图无效,因为FullAjaxExceptionHandler此时已经有错误页面视图,并且不会查看FacesContext更改的视图。您得到一个空白屏幕,因为您的错误页面本身是空白的。

让浏览器自行重定向。利用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>