2011-11-15 166 views
6

我有一個登錄頁面,我有一個用戶bean來驗證用戶的用戶名和密碼。這個Bean是會話作用域。 如果有人寫URL並嘗試跳轉登錄頁面,我該如何檢查並將其重定向到登錄頁面?檢查會話是否存在JSF

另一方面。假設我已經登錄,我正在工作,突然間我出去了一段時間,我的會議到期。當我返回並嘗試與表單進行交互時,它會發送一條消息,提醒我會話到期。如何在發生這種情況時再次將其重定向到登錄表單?

在此先感謝。希望我解釋一下自己。

鑽嘴魚科2.1.4,Tomcat的7,戰斧1.1.11

回答

14

如果有人寫了一個網址,並試圖跳登錄頁面,我怎麼能檢查和重定向他到登錄頁面?

您似乎使用本土認證。在這種情況下,您需要實施servlet filter。 JSF存儲會話範圍內管理豆作爲HttpSession屬性,所以你可以只檢查在doFilter()方法:

HttpServletRequest req = (HttpServletRequest) request; 
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager"); 

if (userManager != null && userManager.isLoggedIn()) { 
    chain.doFilter(request, response); 
} else { 
    HttpServletResponse res = (HttpServletResponse) response; 
    res.sendRedirect(req.getContextPath() + "/login.xhtml"); 
} 

地圖這個過濾器上的URL模式覆蓋保護的頁面,例如/app/*


當我返回並嘗試以發送一條消息,提示我的會話到期的方式進行交互。如何在發生這種情況時再次重定向到登錄表單?

我知道這涉及到Ajax請求嗎?對於正常的請求,您可以在web.xml中使用<error-page>。如果設置在web.xml國家節能法的客戶端如下

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
</context-param> 

是不是一種選擇,那麼你需要實現自定義ExceptionHandler

public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper { 

    private ExceptionHandler wrapped; 

    public ViewExpiredExceptionHandler(ExceptionHandler wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public void handle() throws FacesException { 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 

     for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) { 
      Throwable exception = iter.next().getContext().getException(); 

      if (exception instanceof ViewExpiredException) { 
       facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired"); 
       facesContext.renderResponse(); 
       iter.remove(); 
      } 
     } 

     getWrapped().handle(); 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return wrapped; 
    } 

} 

(注意,這個特殊的例子導航到viewexpired ,所以它期望有一個/viewexpired.xhtml作爲錯誤頁面)

以上需要烘烤的以下ExceptionHandlerFactory implementsat離子:

public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory { 

    private ExceptionHandlerFactory parent; 

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

    @Override 
    public ExceptionHandler getExceptionHandler() { 
     return new ViewExpiredExceptionHandler(parent.getExceptionHandler()); 
    } 

} 

而這又需要faces-config.xml登記如下:

<factory> 
    <exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory> 
</factory> 
+0

我對此有點懷疑。我被要求添加一個名爲「轉到主頁面」的commandLink,但是當我點擊它時,它首先進入ViewExpired頁面,然後我必須再次點擊進入主頁面。如何在沒有單擊commandLink的情況下直接進入主頁面? – BRabbit27

+1

使之成爲一個普通的'',而不需要查看狀態就發送一個新的GET請求。你不需要通過POST提交任何數據,對吧? – BalusC

+0

解決了這個問題,但又出現了另一個問題。如果我留在登錄頁面中,ViewExpiredException也會發生。如何避免這種情況? – BRabbit27

1

如果要實現自己的系統,你可以將屬性添加到用戶名爲會話或什麼的。此屬性可以是布爾值所以無論何時會話開始,您都可以將此屬性設置爲true。寫所謂許可的方法。例如:你想有,你可以在一開始添加以下代碼限制

public void permission() throws IOException { 

     if(userStatelessBean.getSession() == false) { 
      System.out.println("*** The user has no permission to visit this page. *** "); 
      ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); 
      context.redirect("login.xhtml"); 
     } else { 
      System.out.println("*** The session is still active. User is logged in. *** "); 
     } 
    } 

在每個JSF頁面中的(這個例子)您頁:

<f:metadata> 
    <f:event type="preRenderView" listener="#{sesija.permission()}"/> 
</f:metadata> 

這是什麼要做的是渲染頁面之前,對象名稱sesija調用JSF ManagedBean並檢查您在指定的方法創建的rulles是否滿意或不滿意。

我希望你覺得這有用,

謝謝。

+0

U.V.因爲這幫助我管理權限,但這不能回答真正的問題(管理過期視圖) –