使用cookies API获取sessionId而不访问session
我需要在不点击会话的情况下获取当前会话 ID(给它一个过期的机会)。
我使用了 Servlet 代码中的 Cookie,以保持会话不受影响,然后使会话在超时时间后过期。
我正在使用以下代码:
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的代码使会话保持活动状态并且不会超时!
编辑:
我真的卡住了!,我试图放置一个过滤器来删除 JSESSIONID cookie 并删除 HttpServletRequest 中的所有 cookie,但是当我对传递给 servlet 的请求调用 getSession(false) 时,我得到了一个有效的会话!
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[] {});
}
}
真的想忘记所有关于会话的事情,只使用会话 ID 作为用户的唯一标识符,并以困难的方式自己完成。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
至于您的代码,不要采用困难的方式,请使用
HttpServletRequest#getRequestedSessionId()
和HttpServletRequest#isRequestedSessionIdValid()
而是检查请求的会话 ID 及其是否有效。至于你的具体问题:
不,代码不会这样做。这是 HTTP 请求本身完成的。每当您不调用 getSession() 或其他方法时,会话超时都不会被推迟,这是不正确的。无论您在代码中是否需要会话,它都会在客户端触发的每个 HTTP 请求上推迟。
要了解会话的工作原理,您可能会发现此答案很有帮助:servlet 是如何工作的?实例化、会话、共享变量和多线程
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
会话过期并不取决于您的代码是否访问会话,而是取决于用户通过该会话发出请求。每次用户发出请求时,会话的超时时间都会自行重置。
如果您不想让用户的请求重新设置超时(即具有固定长度的会话),那么您将需要执行其他操作来配置会话,包括可能使用不同的会话过滤器来处理会话。
The session expiring isn't dependent on your code accessing the session, it depends on the user making a request with that session. Every time the user makes a request, the session's timeout will reset itself.
If you want to not have the user's request re-set the timeout (ie. have a fixed-length session), then you will need to do additional things for configuring the session, including possibly using a different filter to handle sessions.
会话没有超时,这是正确的行为,因为请求已被接受并且会话过期在任何情况下都会更新。
The session is not timeout, that is correct behavior, because request was accepted and session expiration is updated in any case.