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

时间:2015-10-15 13:34:46

标签: ajax jsf-2 primefaces

当我的会话在我的Java EE 7,JSF Web应用程序中过期时。

我在ajax请求中收到了一个ViewExpiredException。

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

我尝试浏览google和stackoverflow以获得解决方案,但我没有任何运气可以让它与我想要的方式一起工作。

更新:

我尝试了@ 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,登录页面是公共页面。例如,以下xhtml位于安全页面上:

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

这是一个AJAX发布请求,但它被@WebFilter捕获。 (它还与Primefaces中的selectOneMenu一起发生)此过滤器检查用户是否已登录,如果没有,则将其重定向到登录页面。但由于某些原因我使用上面给出的示例按钮,它也被@WebFilter捕获,并且ajax请求获取@WebFilter中指定的响应重定向。它不会被ExceptionHandler捕获。 @WebFilter仅适用于安全页面,见下文。

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

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

1 个答案:

答案 0 :(得分:3)

我在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