2015-10-15 1 views
0

Когда мой сеанс истек в моем Java EE 7, веб-приложении JSF.Переадресация на ViewExpiredException в запросе AJAX в JSF 2

Я получаю исключение ViewExpiredException в запросах ajax.

Я хотел бы перенаправить на страницу, где он показывает пользователю, что сеанс истек.

Я пробовал просматривать google и stackoverflow для решения, но мне не повезло, чтобы он работал с тем, как я этого хочу.

UPDATE:

Я попытался решение отправил @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> 

Но он не работает с этим JSF в странице Xhtml, которая находится на защищенной странице, Логин страница является публичной страницей. Например, следующий XHTML на защищенной странице:

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

Это делает запрос поста AJAX, но он получает поймали мой @WebFilter. (Это также происходит с selectOneMenu от Primefaces). Этот фильтр проверяет, зарегистрирован ли пользователь, если он не перенаправляет их на страницу входа. Но по какой-то причине с приведенной выше кнопкой примера она также попадает в @WebFilter, и запросы ajax получают как перенаправление ответа, указанное в @WebFilter. Он не попадает в ExceptionHandler. @WebFilter применяется только к защищенным страницам, см. Ниже.

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

Кто-нибудь знает, как это решить.

+0

См отредактированный ответ. –

ответ

2

Я делаю это, как это в 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

+0

@Wesley Egbertsen Извините, что это был не мой настоящий код, он отправлен сейчас ... Не могли бы вы проверить, хорошо ли это для вас? Если я правильно помню, у меня возникали проблемы с обнаружением, если это был запрос ajax с предыдущим кодом. –

+1

У меня уже была собственная функция для определения, был ли это Ajax-запрос, я очень близко подошел к решению, но часть из вашего код, в котором вы возвращаете частичный ответ с перенаправлением, сохраненным мной! Вот как я могу проверить если это запрос AJAX: 'частное логическое isAJAXRequest (запрос ServletRequest) { \t HttpServletRequest REQ = (HttpServletRequest) запрос; \t возвращение req.getHeader ("лица-запрос") = нуль \t \t \t && req.getHeader ("лица-запрос") toLowerCase() IndexOf ("Аякс")> -1!..; } ' –