Доступ к сеансу Listern, управляемому контейнером - PullRequest
2 голосов
/ 06 июня 2011

AFAIK, класс слушателя реализации httpsessionlisterner создается при создании первого сеанса.

Поэтому я хотел бы получить доступ к этому экземпляру, потому что мне нужно посчитать, сколько активных сессий, и отобразить его где-нибудь, и я хотел бы проверить, какой пользователь в данный момент входит в систему.В приведенном ниже коде есть переменная экземпляра списка, мне нужно получить доступ к этому классу слушателя для доступа к закрытой переменной.

@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);
  }

Пожалуйста, помогите.

Спасибо.

1 Ответ

1 голос
/ 17 июня 2011

Я должен сделать несколько предположений, поскольку вы не говорите, как работает ваш метод аутентификации.

Я буду предполагать, что ваше имя пользователя будет содержаться в вашем HttpServletRequest (это очень распространено).Если вы специально не закодировали свой сеанс, чтобы он содержал имя пользователя, он не будет содержать имя пользователя, прошедшего аутентификацию, - имя пользователя обычно ограничивается запросом HttpServletRequest.Поэтому вы обычно не достигнете своей цели, используя HttpSessionListener.Вы, наверное, знаете это, но есть разные «возможности».

  • область приложения (ServletContext) - для одного приложения
  • область действия сеанса (HttpSession) - для каждого сеанса
  • область запроса (HttpServletRequest) - для каждого запроса

Как я уже сказал, имя пользователя обычно хранится в области запроса.Вы можете получить доступ к областям сеансов и приложений из области запроса.Вы не можете получить доступ к области запроса из области сеанса (поскольку это не имеет смысла!).

Чтобы решить вашу проблему, я бы создал карту, хранящуюся в области приложения, и использовал бы 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(){}
}

Теперь вы сможете получить информацию о том, кто и сколько пользователей вошел в систему с авторизации Карта, которая хранится в области приложения.

Надеюсь, это поможет,

Отметка

ОБНОВЛЕНИЕ

Моя проверка подлинности выполняется путем проверки имени пользователя и пароляв сервлете и создайте для него новую сессию.

В этом случае 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) {}
}
...