在 JSF 2 的 AJAX 请求中重定向 ViewExpiredException

Redirect on ViewExpiredException in AJAX request in JSF 2

当我的会话在我的 Java EE 7、JSF 网络应用程序中过期时。

我在 ajax 个请求中收到 ViewExpiredException。

我想重定向到一个向用户显示会话已过期的页面。

我尝试浏览 google 和 Whosebug 寻找解决方案,但我没有任何运气让它按照我想要的方式工作。

更新:

我尝试了 posted @ Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request

的解决方案

当我使用 login_submit 按钮时,它确实在我的登录页面上起作用。

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    template="./../templates/login_template.xhtml">

    <ui:define name="title">
        <h:outputText value="#{bundle.login_title}"/>
    </ui:define>

    <ui:define name="content">
        <h:outputText escape="false" value="#{bundle.login_message}"/>
        <h:form>
            <h:panelGrid columns="2" cellpadding="5">
                <h:outputLabel for="username" value="#{bundle.login_username}"/>
                <p:inputText id="username" type="text" value="#{authBean.username}" label="username"/>
                <h:outputLabel for="password" value="#{bundle.login_password}"/>
                <p:inputText id="password" type="password" value="#{authBean.password}"  label="password"/>
                <h:outputText value="#{bundle.login_invalid_password}" rendered="#{!authBean.validPassword and authBean.validUsername}"/>
                <h:outputText value="#{bundle.login_invalid_username}" rendered="#{!authBean.validUsername}"/>
                <p:commandButton value="#{bundle.login_submit}" action="#{authBean.doLogin}"/>
            </h:panelGrid>
        </h:form>
    </ui:define>

</ui:composition>

但它不适用于安全页面上的 xhtml 页面中的此 JSF,登录页面是 public 页面。例如,以下 xhtml 位于安全页面上:

<p:commandButton styleClass="button #{chartBean.isViewButtonActive('MONTH')}" update="dataChart dataTable @form" value="#{bundle.performance_year}" action="#{chartBean.changeModel('MONTH')}" />

这是一个 AJAX post 请求,但它被我的@WebFilter 捕获了。 (它也发生在 Primefaces 的 selectOneMenu 中)这个过滤器检查用户是否登录,如果没有,它会将他们重定向到登录页面。但是出于某种原因,我上面给出的示例按钮也被@WebFilter 捕获,并且 ajax 请求作为@WebFilter 中指定的响应重定向。它不会被 ExceptionHandler 捕获。 @WebFilter 仅适用于安全页面,见下文。

@WebFilter(
        filterName = "AuthorizationFilter",
        urlPatterns = {"/secure/*"},
        dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}
)
public class AuthorizationFilter implements Filter {

有谁知道如何解决这个问题。

我在 webfilter 中这样做,效果很好:

    // Check if user logged in, if not redirect to login.xhtml
    if (loginBean == null || !((LoginBean) loginBean).isLoggedIn()) {
        boolean isAjax = "XMLHttpRequest".equals(req.getHeader("X-Requested-With"));

        if (!isAjax) {
            res.sendRedirect(req.getContextPath() + "/login.xhtml"); 
        } else {
            // Redirecting an ajax request has to be done in the following way:
            // http://javaevangelist.blogspot.com/2013/01/jsf-2x-tip-of-day-ajax-redirection-from.html
            String redirectURL = res.encodeRedirectURL(req.getContextPath() + "/login.xhtml");
            StringBuilder sb = new StringBuilder();
            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><partial-response><redirect url=\"").append(redirectURL).append("\"></redirect></partial-response>");
            res.setCharacterEncoding("UTF-8");
            res.setContentType("text/xml");
            PrintWriter pw = response.getWriter();
            pw.println(sb.toString());
            pw.flush();
        }
    } else {
        // Let chain of filters continue;
        chain.doFilter(request, response);
    }

Inspiration