2016-08-05 5 views
0

다음 문제에 대해 필사적입니다. JSF/PrimeFaces (Wildfly 10)에서는 AJAX 호출과 비 AJAX 호출을 모두 사용합니다. 세션이 만료되고 누군가 시스템과 상호 작용 (클릭)하면 login.xhtml으로 리디렉션되어야하고 사용자에게 새 로그인을 요청해야합니다. 문제는 그것이 AJAX가 아닌 컨트롤에 대해서만 작동한다는 것입니다. 내가 AJAX 컨트롤을 클릭하면, 내가 로그인 페이지에 도착,하지만 난 로그인/암호를 입력하면, 나는 다음과 같은 오류 얻을 : 나는 다음과 같은 클래스 수많은 자료를 읽고 구현 한AJAX 호출에서 부분 응답 메시지와 함께 페이지 리디렉션이 실패합니다.

<partial-response id="j_id1"> 
    <changes> 
     <update id="j_id1:javax.faces.ViewState:0"> 
     <![CDATA[ 982009515771098472:-6468147585577406798 ]]> 
     </update> 
    </changes> 
</partial-response> 

:

JsfAjaxPhaseListener.java

public class JsfAjaxPhaseListener implements PhaseListener { 

    public void beforePhase(PhaseEvent event) { 
    } 

    public PhaseId getPhaseId() { 
     return PhaseId.RESTORE_VIEW; 
    } 

    @Override 
    public void afterPhase(PhaseEvent event) { 
     FacesContext context = FacesContext.getCurrentInstance(); 

     HttpServletRequest httpRequest = (HttpServletRequest) context.getExternalContext().getRequest(); 
     if (httpRequest.getRequestedSessionId() != null && !httpRequest.isRequestedSessionIdValid()) { 
      String facesRequestHeader = httpRequest.getHeader("Faces-Request"); 
      boolean isAjaxRequest = facesRequestHeader != null && facesRequestHeader.equals("partial/ajax"); 

      if (isAjaxRequest) { 
       try { 
        context.getExternalContext().redirect("/admin/login.xhtml"); 
       } catch (IOException ex) { 
        Logger.getLogger(JsfAjaxPhaseListener.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
    } 
} 

SessionExceptionHandler.java

,536,913,632

우리는 다양한 리디렉션, 통화의 다양한 변형을 시도
<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
    <context-param> 
     <param-name>facelets.SKIP_COMMENTS</param-name> 
     <param-value>true</param-value> 
    </context-param> 
    <servlet> 
     <servlet-name>Faces Servlet</servlet-name> 
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>Faces Servlet</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 
    <session-config> 
     <session-timeout> 
      10 
     </session-timeout> 
    </session-config> 
    <welcome-file-list> 
     <welcome-file>admin/index.xhtml</welcome-file> 
    </welcome-file-list> 
    <security-constraint> 
     <display-name>securityConstraint</display-name> 
     <web-resource-collection> 
      <web-resource-name>resources</web-resource-name> 
      <url-pattern>/admin/*</url-pattern> 
     </web-resource-collection> 
     <user-data-constraint> 
      <transport-guarantee>CONFIDENTIAL</transport-guarantee> 
     </user-data-constraint> 
     <auth-constraint> 
      <role-name>Administrator</role-name> 
     </auth-constraint> 
    </security-constraint> 
    <login-config> 
     <auth-method>FORM</auth-method> 
     <realm-name>incomakerSecurityDomain</realm-name> 
     <form-login-config> 
      <form-login-page>/login.xhtml</form-login-page> 
      <form-error-page>/errorLogin.xhtml</form-error-page> 
     </form-login-config> 
    </login-config> 
    <security-role> 
     <role-name>Administrator</role-name> 
    </security-role> 
    <error-page> 
     <error-code>500</error-code> 
     <location>/errorCatchall.xhtml</location> 
    </error-page> 
</web-app> 

, 그것에서 이틀을 보냈다 : 같은 10

public class SessionExceptionHandler extends ExceptionHandlerWrapper { 

    private static final Logger LOGGER = LoggerFactory.getLogger(SessionExceptionHandler.class); 

    private ExceptionHandler wrapped; 

    SessionExceptionHandler(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(); 

      Throwable t = context.getException(); 

      if (t instanceof ViewExpiredException) { 
       ViewExpiredException vee =(ViewExpiredException) t; 
       FacesContext fc =FacesContext.getCurrentInstance(); 
       Map<String, Object> requestMap = fc.getExternalContext().getRequestMap(); 
       NavigationHandler nav = 
         fc.getApplication().getNavigationHandler(); 
       try { 
        ((ConfigurableNavigationHandler)nav).performNavigation("admin/login.xhtml?faces-redirect=true"); 
        fc.renderResponse(); 

       } finally { 
        i.remove(); 
       } 
      } 
     } 
     getWrapped().handle(); 
    } 
} 

SessionExceptionHandlerFactory.java

public class SessionExceptionHandlerFactory extends ExceptionHandlerFactory { 

    private ExceptionHandlerFactory parent; 

    public SessionExceptionHandlerFactory(ExceptionHandlerFactory parent) { 
     this.parent = parent; 
    } 

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

} 

web.xml을 보인다 , 그러나 아무것도 도움이되지 않습니다. 수동으로 로그인 페이지를 다시로드하면 모든 것이 작동합니다. 프로그래밍 방식으로 다시로드하려고하면 부분 응답이 항상 실패합니다.

도움 주셔서 감사합니다.

+0

이 정보가 유용할까요? http://stackoverflow.com/q/35841356 – BalusC

+0

감사합니다. @BalusC. 불행히도, 그것은 작동하지 않는 것 같습니다. 첫째, 우리는 OmniFaces가 아닌 PrimeFaces를 사용합니다. context.getExternalContext() 전에 invalidateSession()을 추가하려했으나 성공하지 못했습니다. 도움이 될 것 같아요 context.getExternalContext(). 리디렉션 대신 ConfigurableNavigationHandler.performNavigation() 사용하는 것입니다,하지만 나는 이유를 잘 모르며 해결 방법이 아닌 해결 방법을 고려해야합니다. :-( – TomS

+1

OmniFaces는 PrimeFaces와 같은 컴포넌트 라이브러리가 아니며 모든 JSF 기반 애플리케이션에서 사용할 수있는 유틸리티 라이브러리입니다 – BalusC

답변

0

BalusC 덕분에 문제는 OmniFaces를 프로젝트에 추가하여 마침내 해결되었습니다. 그런 다음 JsfAjaxPhaseListener 및 SessionExceptionHandler * 클래스를 더 이상 필요하지 않게 제거했습니다. 이제 매력처럼 작동합니다.