I need to get current session Id without hitting the session (to give it a chance to expire).
I’ve used Cookies from Servlet code in order keep the session not-touched and then make the session expires after its timeout time.
I am using the following code:
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;
}
One one OC4J app server, it works fine. although on another oc4j server, the code of accessing cookies makes the session keep active and don’t timeout!
EDIT:
I really stucked!, I’ve trying to place afilter to remove the JSESSIONID cookie and remove all cookies from the HttpServletRequest, but when I call getSession(false) on the request passed to the servlet, I got a valid Session!
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[] {});
}
}
And really think to forget all about Session and just use the session Id as just a unique identifier to the user, and do it myself the hard way.
As to your code, don’t do it the hard way, use
HttpServletRequest#getRequestedSessionId()andHttpServletRequest#isRequestedSessionIdValid()instead to check the requested session ID and if it is valid.As to your concrete problem:
No, the code doesn’t do that. It’s the HTTP request itself which does that. It is not true that whenever you don’t call
getSession()or something, the session timeout won’t be postponed. It will be postponed on every single HTTP request fired by the client, regardless of whether you need the session in the code.To learn about how sessions work, you may find this answer helpful: How do servlets work? Instantiation, sessions, shared variables and multithreading