Java 在不使用cookies API访问会话的情况下获取会话ID
我需要在不点击会话的情况下获取当前会话Id(以使其有机会过期) 我使用了Servlet代码中的Cookies来保持会话不被触动,然后使会话在超时后过期 我正在使用以下代码:Java 在不使用cookies API访问会话的情况下获取会话ID,java,servlets,cookies,session-timeout,Java,Servlets,Cookies,Session Timeout,我需要在不点击会话的情况下获取当前会话Id(以使其有机会过期) 我使用了Servlet代码中的Cookies来保持会话不被触动,然后使会话在超时后过期 我正在使用以下代码: public static String getSessionId(HttpServletRequest request) { String sessionId = ""; String logMsg = ""; if (request != null) { String se
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[] {});
}
}
类CookiierEmovalHttpServletRequestWrapper扩展了HttpServletRequestWrapper
{
公共静态最终字符串COOKIE\u HEADER=“COOKIE”;
公共静态最终字符串jssessionid=“jssessionid”;
公共CookierMemovalHttpServletRequestWrapper(HttpServletRequest请求)
{
超级(请求);
}
@凌驾
公共字符串getHeader(字符串名称)
{
if(COOKIE_头.equalsIgnoreCase(名称))
{
返回“”;
}
返回super.getHeader(name);
}
@凌驾
公共枚举getHeaderNames()
{
枚举e=super.getHeaderNames();
列表l=新的ArrayList();
而(e.hasMoreElements())
{
字符串头名称=(字符串)e.nextElement();
if(!COOKIE_HEADER.equalsIgnoreCase(headerName))
{
l、 添加(headerName);
}
}
返回集合。枚举(l);
}
@凌驾
公共枚举getHeaders(字符串名称)
{
if(COOKIE_头.equalsIgnoreCase(名称))
{
返回新枚举()
{
公共布尔值hasMoreElements()
{
返回false;
}
公共对象nextElement()
{
返回null;
}
};
}
返回super.getHeaders(名称);
}
@凌驾
公共Cookie[]获取cookies()
{
Cookie[]cs=super.getCookies();
List cokRet=新阵列列表(cs.长度);
用于(Cookie c:cs)
{
如果(c.getName().equalsIgnoreCase(JSSessionId))继续;
加入(c);
}
返回cokRet.toArray(新Cookie[]{});
}
}
并且真正地考虑忘记所有关于会话的事情,只使用会话Id作为用户的唯一标识符,然后自己艰难地完成 至于您的代码,不要太费劲,而是使用and检查请求的会话ID以及它是否有效
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
// The session has been expired (or a hacker supplied a fake cookie).
}
关于你的具体问题:
访问cookie的代码使会话保持活动状态,并且不会超时
不,代码没有这样做。这是HTTP请求本身完成的。无论何时不调用getSession()
或其他什么,会话超时都不会被延迟,这是不正确的。无论您是否需要代码中的会话,客户端触发的每一个HTTP请求都会延迟该会话
要了解会话是如何工作的,您可能会发现以下答案很有帮助:至于您的代码,请不要费劲,而是使用和检查请求的会话ID以及它是否有效
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
// The session has been expired (or a hacker supplied a fake cookie).
}
关于你的具体问题:
访问cookie的代码使会话保持活动状态,并且不会超时
不,代码没有这样做。这是HTTP请求本身完成的。无论何时不调用getSession()
或其他什么,会话超时都不会被延迟,这是不正确的。无论您是否需要代码中的会话,客户端触发的每一个HTTP请求都会延迟该会话
要了解会话是如何工作的,您可能会发现以下答案很有帮助:会话过期与访问会话的代码无关,它取决于用户对该会话发出请求。每次用户发出请求时,会话的超时将自行重置
如果您不想让用户的请求重新设置超时(即,有一个固定长度的会话),那么您需要执行其他操作来配置会话,包括可能使用不同的筛选器来处理会话。会话过期不取决于您访问会话的代码,这取决于用户在该会话中发出请求。每次用户发出请求时,会话的超时将自行重置
如果您不想让用户的请求重新设置超时(即,有一个固定长度的会话),那么您需要执行其他操作来配置会话,包括可能使用不同的筛选器来处理会话。会话不是超时,这是正确的行为,因为请求被接受,会话过期在任何情况下都会被更新。会话不是超时,这是正确的行为,因为请求被接受,会话过期在任何情况下都会被更新。是的,但是使用
HttpServletRequest#isRequestedSessionIdValid()
@nico:是的,我现在也看到了OP的意图。我更新了答案。是的,但是通过HttpServletRequest#isRequestedSessionIdValid()
@nico:是的,我现在也看到了OP想要实现的目标。我更新了答案。我添加了一个筛选器(如上图所示),但会话对象似乎是在请求到达任何筛选器/servlet之前创建的(基于cookie
header),这是合乎逻辑的。我添加了一个筛选器(如上图所示),但