在JSF/PrimeFaces ajax请求上的会话超时和ViewExpiredException处理

Mar*_*ada 44 ajax session-timeout primefaces jsf-2 viewexpiredexception

我发现这篇文章对非ajax请求有用如何在JSF 2中处理会话过期和ViewExpiredException? 但是当我使用AJAX调用提交时,我无法使用它.

假设在一个primefaces对话框中,我正在使用AJAX发布一个post请求,session已经超时了.我看到我的页面卡住了.

如何解决这种情况的,这样当我POST使用AJAX,我可以重定向他对我的看法过期的页面,然后转发他类似于上面的链接解决方案登录页面?

JSF2/Primefaces/Glassfish的

Bal*_*usC 47

在ajax请求期间抛出的异常默认情况下在客户端完全没有反馈.只有当您运行Mojarra并将项目阶段设置为Development并使用时<f:ajax>,您才会获得带有异常类型和消息的简单JavaScript警报.但除此之外,在PrimeFaces中,默认情况下根本没有反馈.但是,您可以在服务器日志和ajax响应中看到异常(在webbrowser的开发人员工具集的"网络"部分中).

ExceptionHandlerViewExpiredException队列中有a时,你需要实现一个基本上完成以下工作的自定义:

String errorPageLocation = "/WEB-INF/errorpages/expired.xhtml";
context.setViewRoot(context.getApplication().getViewHandler().createView(context, errorPageLocation));
context.getPartialViewContext().setRenderAll(true);
context.renderResponse();
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用JSF实用程序库OmniFaces.它有一个FullAjaxExceptionHandler出于这样的目的(源代码在这里,展示演示在这里).

也可以看看:

  • 按"提问"按钮并发布SSCCE. (2认同)

Dou*_*ior 18

@BalusC和这篇文章的答案合并,我解决了我的问题!

我的ExceptionHandlerWrapper:

public class CustomExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;

    CustomExceptionHandler(ExceptionHandler exception) {
        this.wrapped = exception;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return wrapped;
    }

    @Override
    public void handle() throws FacesException {
        final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
        while (i.hasNext()) {
            ExceptionQueuedEvent event = i.next();
            ExceptionQueuedEventContext context
                    = (ExceptionQueuedEventContext) event.getSource();

            // get the exception from context
            Throwable t = context.getException();

            final FacesContext fc = FacesContext.getCurrentInstance();
            final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
            final NavigationHandler nav = fc.getApplication().getNavigationHandler();

            //here you do what ever you want with exception
            try {

                //log error ?
                //log.log(Level.SEVERE, "Critical Exception!", t);
                if (t instanceof ViewExpiredException) {
                    requestMap.put("javax.servlet.error.message", "Session expired, try again!");
                    String errorPageLocation = "/erro.xhtml";
                    fc.setViewRoot(fc.getApplication().getViewHandler().createView(fc, errorPageLocation));
                    fc.getPartialViewContext().setRenderAll(true);
                    fc.renderResponse();
                } else {
                    //redirect error page
                    requestMap.put("javax.servlet.error.message", t.getMessage());
                    nav.handleNavigation(fc, null, "/erro.xhtml");
                }

                fc.renderResponse();
                // remove the comment below if you want to report the error in a jsf error message
                //JsfUtil.addErrorMessage(t.getMessage());
            } finally {
                //remove it from queue
                i.remove();
            }
        }
        //parent hanle
        getWrapped().handle();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的ExceptionHandlerFactory:

public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {

    private ExceptionHandlerFactory parent;

    // this injection handles jsf
    public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        ExceptionHandler handler = new CustomExceptionHandler(parent.getExceptionHandler());
        return handler;
    }

}
Run Code Online (Sandbox Code Playgroud)

我的faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

    <factory>
        <exception-handler-factory>
            your.package.here.CustomExceptionHandlerFactory
        </exception-handler-factory>
    </factory>
</faces-config>
Run Code Online (Sandbox Code Playgroud)