- 浏览: 753178 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
lgh1992314:
a offset: 26b offset: 24c offse ...
java jvm字节占用空间分析 -
ls0609:
语音实现在线听书http://blog.csdn.net/ls ...
Android 语音输入API使用 -
wangli61289:
http://viralpatel-net-tutorials ...
Android 语音输入API使用 -
zxjlwt:
学习了素人派http://surenpi.com
velocity宏加载顺序 -
tt5753:
谢啦........
Lucene的IndexWriter初始化时的LockObtainFailedException的解决方法
tomcat 7对sessionId的处理:
首先解析request请求中的sessionID:
从AjpProcessor.java的process(SocketWrapper<Socket> socket)调用CoyoteAdapter.process里面有的postParseRequest(org.apache.coyote.Request req, Request request,org.apache.coyote.Response res,
Response response) 就有解析获取sessionid的过程
// Now we have the context, we can parse the session ID from the URL // (if any). Need to do this before we redirect in case we need to // include the session id in the redirect String sessionID = null; if (request.getServletContext().getEffectiveSessionTrackingModes() .contains(SessionTrackingMode.URL)) { // Get the session ID if there was one sessionID = request.getPathParameter( SessionConfig.getSessionUriParamName( request.getContext())); if (sessionID != null) { request.setRequestedSessionId(sessionID); request.setRequestedSessionURL(true); } } // Look for session ID in cookies and SSL session parseSessionCookiesId(req, request); parseSessionSslId(request); /** * Look for SSL session ID if required. Only look for SSL Session ID if it * is the only tracking method enabled. */ protected void parseSessionSslId(Request request) { if (request.getRequestedSessionId() == null && SSL_ONLY.equals(request.getServletContext() .getEffectiveSessionTrackingModes()) && request.connector.secure) { // TODO Is there a better way to map SSL sessions to our sesison ID? // TODO The request.getAttribute() will cause a number of other SSL // attribute to be populated. Is this a performance concern? request.setRequestedSessionId( request.getAttribute(SSLSupport.SESSION_ID_KEY).toString()); request.setRequestedSessionSSL(true); } } /** * Parse session id in URL. */ protected void parseSessionCookiesId(org.apache.coyote.Request req, Request request) { // If session tracking via cookies has been disabled for the current // context, don't go looking for a session ID in a cookie as a cookie // from a parent context with a session ID may be present which would // overwrite the valid session ID encoded in the URL Context context = (Context) request.getMappingData().context; if (context != null && !context.getServletContext() .getEffectiveSessionTrackingModes().contains( SessionTrackingMode.COOKIE)) { return; } // Parse session id from cookies Cookies serverCookies = req.getCookies(); int count = serverCookies.getCookieCount(); if (count <= 0) { return; } String sessionCookieName = SessionConfig.getSessionCookieName(context); for (int i = 0; i < count; i++) { ServerCookie scookie = serverCookies.getCookie(i); if (scookie.getName().equals(sessionCookieName)) { // Override anything requested in the URL if (!request.isRequestedSessionIdFromCookie()) { // Accept only the first session id cookie convertMB(scookie.getValue()); request.setRequestedSessionId (scookie.getValue().toString()); request.setRequestedSessionCookie(true); request.setRequestedSessionURL(false); if (log.isDebugEnabled()) { log.debug(" Requested cookie session id is " + request.getRequestedSessionId()); } } else { if (!request.isRequestedSessionIdValid()) { // Replace the session id until one is valid convertMB(scookie.getValue()); request.setRequestedSessionId (scookie.getValue().toString()); } } } } }
如果没有sessionId,则在request.getSession()的时候需要进行处理
public class Request implements HttpServletRequest { ...... /** * Return the session associated with this Request, creating one * if necessary. */ @Override public HttpSession getSession() { Session session = doGetSession(true); if (session == null) { return null; } return session.getSession(); } /** * Return the session associated with this Request, creating one * if necessary and requested. * * @param create Create a new session if one does not exist */ @Override public HttpSession getSession(boolean create) { Session session = doGetSession(create); if (session == null) { return null; } return session.getSession(); } // ------------------------------------------------------ Protected Methods protected Session doGetSession(boolean create) { // There cannot be a session if no context has been assigned yet if (context == null) { return (null); } // Return the current session if it exists and is valid if ((session != null) && !session.isValid()) { session = null; } if (session != null) { return (session); } // Return the requested session if it exists and is valid Manager manager = null; if (context != null) { manager = context.getManager(); } if (manager == null) { return (null); // Sessions are not supported } if (requestedSessionId != null) { try { session = manager.findSession(requestedSessionId); } catch (IOException e) { session = null; } if ((session != null) && !session.isValid()) { session = null; } if (session != null) { session.access(); return (session); } } // Create a new session if requested and the response is not committed if (!create) { return (null); } if ((context != null) && (response != null) && context.getServletContext().getEffectiveSessionTrackingModes(). contains(SessionTrackingMode.COOKIE) && response.getResponse().isCommitted()) { throw new IllegalStateException (sm.getString("coyoteRequest.sessionCreateCommitted")); } // Attempt to reuse session id if one was submitted in a cookie // Do not reuse the session id if it is from a URL, to prevent possible // phishing attacks // Use the SSL session ID if one is present. if (("/".equals(context.getSessionCookiePath()) && isRequestedSessionIdFromCookie()) || requestedSessionSSL ) { session = manager.createSession(getRequestedSessionId()); } else { session = manager.createSession(null); } // Creating a new session cookie based on that session if ((session != null) && (getContext() != null) && getContext().getServletContext(). getEffectiveSessionTrackingModes().contains( SessionTrackingMode.COOKIE)) { Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie( context, session.getIdInternal(), isSecure()); response.addSessionCookieInternal(cookie); } if (session == null) { return null; } session.access(); return session; } ...... ......
上面会通过manager.createSession创建session,如果request请求带了sessionId,则传入该参数
,没有的话则会创建一个,并且会把sessionId放入response的cookie中
manager对应ManagerBase.java类,里面生成session的过程如下:
/** * Construct and return a new session object, based on the default * settings specified by this Manager's properties. The session * id specified will be used as the session id. * If a new session cannot be created for any reason, return * <code>null</code>. * * @param sessionId The session id which should be used to create the * new session; if <code>null</code>, a new session id will be * generated * @exception IllegalStateException if a new session cannot be * instantiated for any reason */ @Override public Session createSession(String sessionId) { if ((maxActiveSessions >= 0) && (getActiveSessions() >= maxActiveSessions)) { rejectedSessions++; throw new IllegalStateException( sm.getString("managerBase.createSession.ise")); } // Recycle or create a Session instance Session session = createEmptySession(); // Initialize the properties of the new session and return it session.setNew(true); session.setValid(true); session.setCreationTime(System.currentTimeMillis()); session.setMaxInactiveInterval(this.maxInactiveInterval); String id = sessionId; if (id == null) { id = generateSessionId(); } session.setId(id); sessionCounter++; SessionTiming timing = new SessionTiming(session.getCreationTime(), 0); synchronized (sessionCreationTiming) { sessionCreationTiming.add(timing); sessionCreationTiming.poll(); } return (session); } /** * Generate and return a new session identifier. */ protected String generateSessionId() { String result = null; do { if (result != null) { // Not thread-safe but if one of multiple increments is lost // that is not a big deal since the fact that there was any // duplicate is a much bigger issue. duplicates++; } result = sessionIdGenerator.generateSessionId(); } while (sessions.containsKey(result)); return result; } ......
sesseionIdGenerator生成sessionId的算法如下:
/** * Generate and return a new session identifier. */ public String generateSessionId() { byte random[] = new byte[16]; // Render the result as a String of hexadecimal digits StringBuilder buffer = new StringBuilder(); int resultLenBytes = 0; while (resultLenBytes < sessionIdLength) { getRandomBytes(random); for (int j = 0; j < random.length && resultLenBytes < sessionIdLength; j++) { byte b1 = (byte) ((random[j] & 0xf0) >> 4); byte b2 = (byte) (random[j] & 0x0f); if (b1 < 10) buffer.append((char) ('0' + b1)); else buffer.append((char) ('A' + (b1 - 10))); if (b2 < 10) buffer.append((char) ('0' + b2)); else buffer.append((char) ('A' + (b2 - 10))); resultLenBytes++; } } if (jvmRoute != null && jvmRoute.length() > 0) { buffer.append('.').append(jvmRoute); } return buffer.toString(); }
其中jvmRoute是为了防止tomcat集群导致的sessionId冲突,getRandomBytes(random);会通过随机算法生成16byte的字节数组,最终sessionId默认是生成16byte的字符串。
上面说到会把生成的sessionId存入response的cookie域中
Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie( context, session.getIdInternal(), isSecure()); response.addSessionCookieInternal(cookie);
处理过程如下:
/** * Special method for adding a session cookie as we should be overriding * any previous * @param cookie */ public void addSessionCookieInternal(final Cookie cookie) { if (isCommitted()) { return; } String name = cookie.getName(); final String headername = "Set-Cookie"; final String startsWith = name + "="; final StringBuffer sb = generateCookieString(cookie); boolean set = false; MimeHeaders headers = coyoteResponse.getMimeHeaders(); int n = headers.size(); for (int i = 0; i < n; i++) { if (headers.getName(i).toString().equals(headername)) { if (headers.getValue(i).toString().startsWith(startsWith)) { headers.getValue(i).setString(sb.toString()); set = true; } } } if (!set) { addHeader(headername, sb.toString()); } }
如果header已经有这个sessionId的cookie,则更新,否则设置到header中。
评论
2 楼
featuretower
2013-03-08
public class Request
implements HttpServletRequest {
Request是什么类来的,在doGetSession里context是它的私有变量? context是什么类型呢,什么时候初始化??
implements HttpServletRequest {
Request是什么类来的,在doGetSession里context是它的私有变量? context是什么类型呢,什么时候初始化??
1 楼
z276356445t
2012-07-30
tomcat不是一直都将JSESSIONID放入cookie中的?
发表评论
-
apache安全配置tips
2013-10-17 09:39 1255原文:http://www.javaarch.net/ ... -
apache url rewrite 的RewriteRule参数详解
2013-06-18 09:43 8705原文链接:http://www.java ... -
tomcat和jetty对静态资源的处理和客户端缓存的处理
2013-06-16 15:41 6296tomcat和jetty对静态资源的处理和客户端缓存的处理 ... -
tomcat限制ip访问
2013-06-01 15:27 1989tomcat限制ip访问 原文:http://www.j ... -
apache模块开发之content hander,读取配置,输出内容替换过滤器,url域名替换过滤器
2013-04-15 23:19 1037apache-replace-module 代 ... -
accesslog或者cookie'log的shell常用分析脚本
2013-03-28 21:56 1470#统计apache cookie log中访问频率最高的20 ... -
ubutun apache源码完整安装过程
2012-11-09 23:27 9131.到这里下载apache的最新版2.4.3 http: ... -
jetty防止Dos攻击的filter实现分析
2012-07-29 15:13 1165jetty的org.eclipse.jetty.servlet ... -
jetty对sessionId的处理分析
2012-07-29 10:53 3103jetty7对sessionId的处理,首先入口在Sessio ... -
apache的unix MPM模块简介
2011-11-26 15:48 1111UNIX下的apache MPM:MPM模块: ... -
apache查看已安装模块
2010-12-28 18:31 2206apache可以用一下两种方式查看已经安装的静态模块 ...
相关推荐
通过上述分析,我们可以看到,Tomcat Redis Session Manager提供了便捷的session共享机制,有效地解决了高并发场景下的session管理问题。通过对源码的学习和实践,开发者可以更好地理解和掌握这一技术,提升系统的可...
本文将深入探讨如何在Tomcat中实现Session的共享,并分析其背后的原理和配置方法。 首先,我们要理解Session的基本概念。Session是Web服务器为用户创建的一段持久性存储空间,用于存储用户在访问网站期间产生的状态...
`RedisSession`是`RedisSessionManager`内部用于表示会话的对象,它继承自`org.apache.catalina.Session`,并扩展了对Redis特性的支持,如序列化和反序列化。会话数据在Redis中以哈希(Hash)形式存储,便于高效地...
总结来说,Tomcat中的Session是通过Session ID(JSESSIONID)作为标识,结合Cookie在客户端和服务器之间传递,实现对用户会话状态的跟踪。了解这些原理对于优化Web应用性能、处理会话管理问题以及确保用户安全性至关...
总结,Tomcat6源码分析是深入了解Web服务器运行机制的重要途径,通过对源码的学习,我们可以掌握其内部的工作原理,从而在实际开发中实现更高效、更稳定的应用部署和维护。这是一份宝贵的资源,值得我们深入研究和...
【深入浅析TomCat Session管理分析】 Session在Java Web开发中扮演着至关重要的角色,它允许服务器跟踪用户的交互,存储用户的状态信息。Tomcat作为广泛使用的开源Servlet容器,其内部的Session管理机制对于理解Web...
1. 创建:当用户首次访问应用并请求Session时,Tomcat会通过`SessionIdGenerator`生成一个唯一的Session ID,然后创建一个新的Session对象。 2. 获取:通过`request.getSession()`方法,Tomcat检查请求头中的...
在IT行业中,构建高效、可扩展的Web应用架构是至关重要的。本压缩包"**Nginx.tomcat....通过对Nginx、Tomcat、Memcached的合理利用和集成,我们可以构建出一个稳定、可扩展且能有效处理Session共享问题的Web服务系统。
Tomcat提供会话跟踪,通过Session ID来识别用户会话。会话管理包括创建、更新、过期和移除会话。默认使用Cookie进行会话追踪,但也可以配置为URL重写或基于SSL的会话追踪。 7. **安全性** Tomcat通过JaasRealm和...
每个用户登录时,会生成一个唯一的Session ID,用于标识该用户,然后通过这个ID来区分不同的聊天会话。 多对多聊天则相对复杂一些,它涉及到多个用户之间的消息广播。为了实现这一点,可能需要一个公共的消息队列...
Session ID存储在cookie中,服务器通过Session Manager和Session ID跟踪用户会话。 6. **安全性** Tomcat支持多种安全策略,如SSL/TLS加密, Realm(认证域)进行用户身份验证,以及角色授权。可以通过` Realm `...
当客户端请求携带会话ID时,Tomcat根据ID查找并恢复会话状态。此外,Tomcat还支持会话超时、分布式会话和会话持久化等高级功能。 5. **安全性与权限控制** Tomcat使用Realm组件进行身份验证,如MemoryRealm、...
每当用户发送请求时,浏览器会通过Cookie将这个Session ID返回给服务器,服务器根据ID找到对应的Session数据,实现对用户状态的跟踪。 Session的实现通常涉及到以下步骤: 1. 用户首次访问网站时,服务器生成一个...
Session是服务器端保持用户状态的一种方式,当客户端发送请求时,Tomcat会检查Cookie中的Session ID,如果存在,就从内存或持久化存储中恢复相关的Session数据。此外,Tomcat提供了会话跟踪模块,如URL重写、隐藏...
通过合理的配置和对对象的序列化处理,可以有效避免因Session管理不当而导致的异常,提高系统的稳定性和用户体验。 通过本篇文章的学习,我们可以更好地理解和掌握Java Session的相关知识点,为日常的Web开发工作...
通过对Tomcat源码的深入学习,我们可以更好地理解其内部工作原理,从而更好地优化应用性能,解决运行时问题,甚至为Tomcat开发新的功能或模块。这个过程不仅提升了编程技能,也为参与其他Java Web项目的开发打下了...
Tomcat支持会话跟踪,使用session ID来识别用户会话。源码揭示了会话创建、过期、复制和分布式管理的实现。 7. **JSP编译**: Jasper组件负责JSP文件的编译成Servlet。通过源码,开发者可以理解JSP到Servlet的...
例如,可以使用Servlet容器(如Tomcat)的内置Session持久化配置,或者自定义实现`HttpSessionListener`和`HttpSessionBindingListener`来监听Session的创建和销毁事件,进行手动持久化操作。 标签中的"源码"可能...
在分布式系统中,特别是使用 Nginx 作为反向代理服务器与多台 Tomcat 应用服务器集群配合时,会话粘性(Session Stickiness)是一个重要的考虑因素。会话粘性是指确保来自同一用户的请求被转发到同一台后端服务器,...