2012-01-24 7 views
0

Мне нужно получить текущий идентификатор сеанса без удара сессии (чтобы дать ему шанс истечь).Получение sessionId без доступа к сеансу с использованием файлов cookie API

Я использовал Cookies из кода сервлета, чтобы сеанс не был затронут, а затем закончил сеанс после истечения времени ожидания.

Я использую следующий код: сервер приложений

public static String getSessionId(HttpServletRequest request) 
{ 
    String sessionId = ""; 
    String logMsg = ""; 
    if (request != null) 
    { 
     String sessionTimeout = PropertiesReader.SESSION_TIMEOUT_SCHEMA; 
     if (sessionTimeout != null && SessionHelper.SESSION_TIMEOUT_FIXED.equalsIgnoreCase(sessionTimeout)) 
     { 
      logMsg = "FIXED: Getting SessionId from Cookies with activating the session"; 
      Cookie[] cookies = request.getCookies(); 
      if (cookies != null) 
      { 
       for (Cookie cook : cookies) 
       { 
        if ("JSESSIONID".equalsIgnoreCase(cook.getName())) 
        { 
         sessionId = cook.getValue(); 
         break; 
        } 
       } 
      } 
     } else 
     { 
      logMsg = "PER_USAGE: Getting SessionId from Session"; 
      sessionId = request.getSession(false) != null ? request.getSession(false).getId() : ""; 
     } 
    }else 
    { 
     logMsg = "Request object is null"; 
    } 

    logger.info(logMsg + ", sessionId=" + sessionId); 

    return sessionId; 
} 

Один один OC4J, он отлично работает. хотя на другом сервере oc4j код доступа к файлам cookie делает сеанс активным и не отключается!

EDIT:

Я действительно stucked !, Я пытаюсь поместить afilter удалить куки JSESSIONID и удалить все куки из HTTPServletRequest, но когда я называю getSession (ложь) по запросу передается сервлет, я получил действительный сеанс!

class CookieRemovalHttpServletRequestWrapper extends HttpServletRequestWrapper 
    { 
     public static final String COOKIE_HEADER = "cookie"; 
     public static final String JSESSIONID = "JSESSIONID"; 

     public CookieRemovalHttpServletRequestWrapper(HttpServletRequest request) 
     { 
      super(request); 
     } 

     @Override 
     public String getHeader(String name) 
     { 
      if (COOKIE_HEADER.equalsIgnoreCase(name)) 
      { 
       return ""; 
      } 
      return super.getHeader(name); 
     } 

     @Override 
     public Enumeration getHeaderNames() 
     { 
      Enumeration e = super.getHeaderNames(); 
      List l = new ArrayList(); 
      while (e.hasMoreElements()) 
      { 
       String headerName = (String) e.nextElement(); 
       if (!COOKIE_HEADER.equalsIgnoreCase(headerName)) 
       { 
        l.add(headerName); 
       } 
      } 

      return Collections.enumeration(l); 
     } 

     @Override 
     public Enumeration getHeaders(String name) 
     { 
      if (COOKIE_HEADER.equalsIgnoreCase(name)) 
      { 
       return new Enumeration() 
       { 
        public boolean hasMoreElements() 
        { 
         return false; 
        } 

        public Object nextElement() 
        { 
         return null; 
        } 
       }; 
      } 
      return super.getHeaders(name); 
     } 

     @Override 
     public Cookie[] getCookies() 
     { 
      Cookie[] cs = super.getCookies(); 
      List<Cookie> cokRet = new ArrayList<Cookie>(cs.length); 
      for (Cookie c : cs) 
      { 
       if (c.getName().equalsIgnoreCase(JSESSIONID)) continue; 
       cokRet.add(c); 
      } 

      return cokRet.toArray(new Cookie[] {}); 
     } 

    } 

И действительно думаю, что забыть о сессии и просто использовать идентификатор сеанса, как только уникальный идентификатор для пользователя, и сделать это сам жесткий путь.

ответ

5

Что касается вашего кода, не делайте этого трудным путем, используйте HttpServletRequest#getRequestedSessionId() и HttpServletRequest#isRequestedSessionIdValid() вместо этого, чтобы проверить запрошенный идентификатор сеанса и, если он действителен.

if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) { 
    // The session has been expired (or a hacker supplied a fake cookie). 
} 

Как к вашей конкретной проблеме:

код доступа печеньем делает сеанс вести активный образ жизни и не тайм-аут!

Нет, код этого не делает. Это сам запрос HTTP. Неверно, что всякий раз, когда вы не вызываете getSession() или что-то, тайм-аут сеанса не будет отложен. Он будет отложен на каждый HTTP-запрос, запущенный клиентом, независимо от того, нужен ли вам сеанс в коде.

Чтобы узнать о том, как работают сессии, вы можете найти этот ответ полезным: How do servlets work? Instantiation, sessions, shared variables and multithreading

+0

Да, но с 'HttpServletRequest # isRequestedSessionIdValid()' –

+0

@nico: да, теперь я также вижу, чего намерен сделать OP. Я обновил ответ. – BalusC

1

Сеанс Истекает срок действия не зависит от кода доступа к сеансу, это зависит от пользователя делает запрос с этой сессии. Каждый раз, когда пользователь делает запрос, тайм-аут сеанса сбрасывается.

Если вы хотите, чтобы не имел запрос пользователя повторно установить тайм-аут (т. Е. Иметь сеанс фиксированной длины), вам нужно будет сделать дополнительные вещи для настройки сеанса, в том числе, возможно, с использованием другого фильтра для обработки сеансов.

+0

Я добавил фильтр (показано выше), но кажется, что объект сеанса создается (на основе 'cookie'), прежде чем даже запрос достигнет любого фильтра/сервлета, и это логично. –

0

Сессия не является таймаутом, это правильное поведение, поскольку запрос был принят, и срок действия сеанса обновлен в любом случае.