2014-01-16 35 views
0

我有一個用JSF 2編寫的主頁。當我在主頁上點擊'註冊'時,它會通過MyController這是一個NamedSession scoped bean。從JSF中的會話中排除公共頁面

我的問題是,如果用戶打開主頁,等到會話過期並點擊'註冊'鏈接,我們會得到一個ViewExpiredException。

我們如何排除主頁中的鏈接以排除會話?

+0

那麼如果您使用的是最新版本的JSF 2.x,那麼您可以選擇使用新的無狀態視圖功能,這可能會防止這樣的問題。 http://balusc.blogspot.nl/2013/02/stateless-jsf.html。我從來沒有測試過,所以這就是爲什麼我不把它作爲答案。 – Gimby

回答

0

對付你需要實現一個ExceptionHandlerWrapper和工廠ViewExpiredExceptions:

的ExceptionHandler:

import java.io.Serializable; 
import java.util.Iterator; 

import javax.faces.FacesException; 
import javax.faces.application.NavigationHandler; 
import javax.faces.application.ViewExpiredException; 
import javax.faces.context.ExceptionHandler; 
import javax.faces.context.ExceptionHandlerWrapper; 
import javax.faces.context.FacesContext; 
import javax.faces.event.ExceptionQueuedEvent; 
import javax.faces.event.ExceptionQueuedEventContext; 

public class SystemNaviExceptionHandler extends ExceptionHandlerWrapper implements Serializable { 

    private static final long serialVersionUID = -1865349922998154148L; 
    private ExceptionHandler parent; 

    public SystemNaviExceptionHandler(ExceptionHandler parent) { 
     this.parent = parent; 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return this.parent; 
    } 

    @Override 
    public void handle() throws FacesException { 
     for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) { 
      ExceptionQueuedEvent event = i.next(); 
      System.out.println("Iterating over ExceptionQueuedEvents. Current:" + event.toString()); 
      ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource(); 
      Throwable t = context.getException(); 
      if (t instanceof ViewExpiredException) { 
       ViewExpiredException vee = (ViewExpiredException) t; 
       FacesContext fc = FacesContext.getCurrentInstance(); 

       NavigationHandler nav = 
         fc.getApplication().getNavigationHandler(); 
       try { 
        // Push some stuff to the flash scope for use in the page 
        fc.getExternalContext().getFlash().put("expiredViewId", vee.getViewId()); 
        // i do a redirect to login page 
        nav.handleNavigation(fc, null, "client-login"); 
        fc.renderResponse(); 

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

     getWrapped().handle(); 
    } 
} 

和工廠類:

import java.io.Serializable; 

import javax.faces.context.ExceptionHandler; 

public class ExceptionHandlerFactory extends javax.faces.context.ExceptionHandlerFactory implements Serializable { 

    private static final long serialVersionUID = 4685303865999111737L; 
    private javax.faces.context.ExceptionHandlerFactory parent; 

    public ExceptionHandlerFactory(javax.faces.context.ExceptionHandlerFactory parent) { 
     this.parent = parent; 
    } 

    @Override 
    public ExceptionHandler getExceptionHandler() { 
     ExceptionHandler result = parent.getExceptionHandler(); 
     result = new SystemNaviExceptionHandler(result); 
     return result; 
    } 

} 

在註冊工廠類的faces-config.xml:

<factory> 
     <exception-handler-factory>path.to.factoryClass.ExceptionHandlerFactory</exception-handler-factory> 
    </factory>