2011-06-06 31 views
2

AFAIK,httpsessionlisterner實現偵聽器類在創建第一個會話時得到實例化。訪問由容器管理的會話Listern

因此,我想訪問這個實例,因爲我需要計算多少活動會話,並顯示它在哪裏,我想檢查哪個用戶當前登錄。在下面的代碼中,有列表實例變量,我需要訪問此偵聽器類才能訪問私有變量。

@WebListener() 
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener { 

    private List<HttpSession> sessionList; 

    public SessionListener() { 
    sessionList = new ArrayList<HttpSession>(); 
    } 

    @Override 
    public void sessionCreated(HttpSessionEvent se) { 
    sessionList.add(se.getSession()); 
    } 

    @Override 
    public void sessionDestroyed(HttpSessionEvent se) { 
    sessionList.remove(se.getSession()); 
    } 

    @Override 
    public void attributeAdded(HttpSessionBindingEvent event) { 
    } 

    @Override 
    public void attributeRemoved(HttpSessionBindingEvent event) { 

    } 

    @Override 
    public void attributeReplaced(HttpSessionBindingEvent event) { 

    } 

    /** 
    * @return the sessionList 
    */ 
    public List<HttpSession> getSessionList() { 
    return Collections.unmodifiableList(sessionList); 
    } 

請大家幫忙。

謝謝。

+0

謝謝。請幫忙。 – peterwkc 2011-06-09 01:23:55

+0

任何人都請幫助我。 – peterwkc 2011-06-10 08:36:14

+0

Wooh。我以爲有人可以啓發我。請幫忙。 – peterwkc 2011-06-15 02:56:19

回答

1

我不得不做出一些假設,因爲您沒有說明您的身份驗證方法是如何工作的。

我會假設你的用戶名將被包含在你的HttpServletRequest中(這是很常見的)。除非您特別編寫會話以包含用戶名,否則將不包含經過身份驗證的用戶的用戶名 - 用戶名通常僅限於HttpServletRequest。因此,通常不會通過使用HttpSessionListener實現您的目標。你可能知道這一點,但有各種「範圍」。

  • 應用範圍(ServletContext中) - 每次施用
  • 會話範圍(的HttpSession) - 每個會話
  • 請求範圍(HttpServletRequest的) - 每個請求

正如我說的用戶名通常存儲在請求範圍內。您可以從請求範圍訪問會話和應用程序範圍。您無法從會話範圍訪問請求範圍(因爲這沒有意義!)。

爲了解決您的問題,我會創建一個存儲在應用程序範圍中的Map並使用ServletFilter來填充它。您可能希望使用基於時間的高速緩存(使用會話超時值)而不是直接映射,因爲大多數會話都已啓動,但超時而不是由用戶明確終止。 kitty-cache是一個非常簡單的基於時間的緩存,可以用於此目的。

反正代碼草圖(未經測試)可能是這個樣子:

public class AuthSessionCounter implements Filter { 

    private static final String AUTHSESSIONS = "authsessions"; 
    private static ServletContext sc; 

    public void init(FilterConfig filterConfig) throws ServletException { 
     sc = filterConfig.getServletContext(); 
     HashMap<String, String> authsessions = new HashMap<String, String>(); 
     sc.setAttribute(AUTHSESSIONS, authsessions); 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest hsr = (HttpServletRequest) request; 
     if (hsr.getRemoteUser() != null) {    
      HttpSession session = hsr.getSession(); 
      HashMap<String, String> authsessions = (HashMap<String, String>) sc.getAttribute(AUTHSESSIONS); 
      if (!authsessions.containsKey(session.getId())) { 
       authsessions.put(session.getId(), hsr.getRemoteUser()); 
       sc.setAttribute(AUTHSESSIONS, authsessions); 
      } 
     } 
     chain.doFilter(request, response); 
    } 

    public void destroy(){} 
} 

您現在應該能夠得到誰,有多少用戶從authsessions地圖登錄的細節存儲在應用程序範圍中。

我希望這有助於

馬克

UPDATE

我的認證是由servlet的 檢查 的用戶名和密碼的作品,併爲它創建一個新的會話。

在這種情況下,HttpSessionListener可能爲你工作 - 雖然我之前提到的,你可能仍然需要使用基於時間的緩存由於的方式,大多數用戶會話超時,而不是結束。我未經測試的代碼草圖現在看起來像這樣:

public class SessionCounter 
    implements HttpSessionListener, HttpSessionAttributeListener { 

    private static final String AUTHSESSIONS = "authsessions"; 
    private static final String USERNAME = "username"; 
    private static ServletContext sc; 

    public void sessionCreated(HttpSessionEvent se) { 
     if (sc == null) { 
      sc = se.getSession().getServletContext(); 
      HashMap<String, String> authsessions = new HashMap<String, String>(); 
      sc.setAttribute(AUTHSESSIONS, authsessions); 
     } 
    } 

    public void sessionDestroyed(HttpSessionEvent se) { 
     HttpSession session = se.getSession(); 
     HashMap<String, String> authsessions = 
      (HashMap<String, String>) sc.getAttribute(AUTHSESSIONS); 
     authsessions.remove(session.getId()); 
     sc.setAttribute(AUTHSESSIONS, authsessions); 
    } 

    public void attributeAdded(HttpSessionBindingEvent se) { 
     if (USERNAME.equals(se.getName())) { 
      HttpSession session = se.getSession(); 
      HashMap<String, String> authsessions = 
        (HashMap<String, String>) sc.getAttribute(AUTHSESSIONS); 
      authsessions.put(session.getId(), (String) se.getValue()); 
      sc.setAttribute(AUTHSESSIONS, authsessions); 
     } 
    } 

    public void attributeRemoved(HttpSessionBindingEvent se) {} 

    public void attributeReplaced(HttpSessionBindingEvent se) {} 
} 
+0

我的身份驗證通過檢查servlet中的用戶名和密碼併爲其創建新會話來起作用。 – peterwkc 2011-06-20 10:54:30