session 是记录服务器会话的一个对象,他可以跟踪用户从登陆到关闭浏览器一系列动作,具体的创建代码
public void addSession(HttpServletRequest request,String key,String value){ HttpSession session = request.getSession(); session.setAttribute(key, value); }
通过 HttpServletRequest 对象获取session 对象, 对应的tomcat 下的org.apache.catalina.connector.RequestFacade 的 getSession()方法
@Override public HttpSession getSession() { if (request == null) { throw new IllegalStateException( sm.getString("requestFacade.nullRequest")); } return getSession(true); }
调用 getSession(create) 方法
@Override //create 参数就是是否创建session 如果false,服务器中不存在对应的session,则返回null public HttpSession getSession(boolean create) { if (request == null) { throw new IllegalStateException( sm.getString("requestFacade.nullRequest")); } if (SecurityUtil.isPackageProtectionEnabled()){ return AccessController. doPrivileged(new GetSessionPrivilegedAction(create)); } else { return request.getSession(create); } }
将获取session转交给org.apache.catalina.connector.Request 类处理,RequestFacade 是Request 类的一个门面类,他包装了Request 的方法调用,对外开放,隐藏了Request 的实现细节,
调用了 Request 类的getSession(create) 方法
@Override public HttpSession getSession(boolean create) { //处理获取session Session session = doGetSession(create); if (session == null) { return null; } return session.getSession(); }
Session session = doGetSession(create); 这个session 是tomcat的session 接口,不是 java.javax 下的。
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 } //如果cookie 中的jsessionId ,或者是URL paramaters不为空, // 通过manager 管理器查找session
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; }
其中requestedSessionId 是 org.apache.catalina.connector.CoyoteAdapter 下的postParseRequest方法解析的,具体代码片段
// 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); sessionID = request.getRequestedSessionId();
对session 的管理 是Manager 接口, org.apache.catalina 包下的。具体是实现类 是ManagerBase
//如果cookie 中的jsessionId ,或者是URL paramaters不为空,通过manager 管理器查找session 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); } }
对应ManagerBase 类中的
@Override public Session findSession(String id) throws IOException { if (id == null) return (null); return sessions.get(id); }
sessions 是ManagerBase 对象的一个属性,
protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();
用并发的HashMap 来存放session信息,其中Key 值就是cookie 中对应的jsessionId,如果找到就返回找到的session 对象,如果没有找到并且create 参数是false ,表示不创建session 则 返回null,如果是true 就是创建session 对象,具体的创建session 对象的代码片段为:
//判断cookie 中是否有jsessionId 如果有,就使用这个jsessionId ,如果没有就创建新的jsessionId if (("/".equals(context.getSessionCookiePath()) && isRequestedSessionIdFromCookie()) || requestedSessionSSL) { session = manager.createSession(getRequestedSessionId()); } else { session = manager.createSession(null); } //创建一个新的session cookie,基于刚刚创建好的session if ((session != null) && (getContext() != null) && getContext().getServletContext() .getEffectiveSessionTrackingModes() .contains(SessionTrackingMode.COOKIE)) { Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie( context, session.getIdInternal(), isSecure()); response.addSessionCookieInternal(cookie); }
关于session 中 cookie name 值默认是JSESSIONID ,如果在web.xml 中配置了session-config ,其中cookie-config 下的name 就是sessionCookieName 值,如果没有配置的话,就是默认
具体代码如下:
public static String getSessionCookieName(Context context) { String result = getConfiguredSessionCookieName(context); if (result == null) { result = DEFAULT_SESSION_COOKIE_NAME; } return result; }
具体创建session 的逻辑在ManagerBase 中
public Session createSession(String sessionId) { if ((maxActiveSessions >= 0) && (getActiveSessions() >= maxActiveSessions)) { rejectedSessions++; throw new TooManyActiveSessionsException( sm.getString("managerBase.createSession.ise"), maxActiveSessions); } //创建一个空的session ,其实就是创建org.apache.catalina.session.StandardSession 对象,将该对象交由manager 管理 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) { //生成sessionId,具体的生成SessionId 的逻辑在org.apache.catalina.util.SessionIdGenerator 下的generateSessionId 方法, id = generateSessionId(); } session.setId(id); sessionCounter++; SessionTiming timing = new SessionTiming(session.getCreationTime(), 0); synchronized (sessionCreationTiming) { sessionCreationTiming.add(timing); sessionCreationTiming.poll(); } return (session); }
以上就是创建HttpSession 的过程, 都是个人的理解,由于个人水平有限,还有很多地方没有讲清楚或者说错了,例如session 的持久化技术,具体可以参考 org.apache.catalina.session.StoreBase ,tomcat 提供两种持久化机制,分布是文件持久化,和jdbc 数据持久化 对应的类是FileStore,JDBCStore
相关推荐
【标题】:“Tomcat Redis Session”指的是在Tomcat集群环境中,通过Redis来实现Session的共享与同步,以解决集群中的Session一致性问题。 【描述】:“Tomcat集群Nginx使用Redis保证Session同步”这一场景中,通常...
总结起来,Tomcat5 的 Session 复制通过集群配置和 Web 应用配置两方面实现,确保了分布式环境下的会话一致性。配置过程中需注意端口冲突、网络可达性以及正确设置复制策略,以达到高效且稳定的 Session 同步效果。
4.2 WebSocket:Tomcat7及以上版本支持WebSocket协议,实现双向通信,常用于实时聊天、游戏等场景。 4.3 SSL/TLS安全:Tomcat可以配置SSL连接,确保数据传输的安全性,支持各种证书类型和加密算法。 五、优化与...
从提供的链接中获取memcached-session-manager及其依赖的jar包,如memcached-session-manager-${version}.jar,memcached-session-manager-tc6或tc7-${version}.jar,spymemcached-2.7.3.jar等,根据Tomcat版本选择...
7. **MVC模式**:在JavaWeb开发中,Model-View-Controller模式被广泛使用,理解如何在Tomcat中实现这一模式,例如使用Spring MVC框架。 8. **session和cookie管理**:掌握如何在Web应用中实现用户会话管理和状态...
本文介绍了如何在JDK 1.8.0_131和Tomcat 8环境下搭建一个简单的Tomcat集群,并实现了Session共享。通过这些步骤,不仅可以提高系统的性能和可用性,还能更好地应对高并发场景下的访问需求。希望本文对您有所帮助!
【描述】:“Memcached-session-manager所需的jar包-tomcat7-kryo序列”意味着为了实现Tomcat7服务器对用户会话的高效存储和管理,开发者选择了Memcached-session-manager这一中间件,并且采用了Kryo序列化技术。...
《Tomcat与Java Web开发技术详解》是孙卫琴老师撰写的一本深入解析Java Web开发和Tomcat服务器的著作,其第二版进一步更新了内容,提供了更为详尽的指导。这本书针对初学者和有一定经验的开发者,旨在帮助读者掌握...
源代码压缩包"Tomcat与Java Web开发技术详解源代码.rar"包含了书中所有示例的完整实现,为读者提供了动手实践的宝贵资源。 首先,Tomcat是Apache软件基金会下的一个开源项目,是一款轻量级的应用服务器,主要支持...
《Tomcat与Java Web开发技术详解(第2版)》是由孙卫琴编著的一本深入探讨Java Web开发和Tomcat应用服务器的经典书籍。这本书详细介绍了如何使用Tomcat进行Java Web应用程序的部署和运行,是Java开发者的重要参考资料...
Tomcat 5是Apache软件基金会的Jakarta项目中的一个核心项目,是一个开源的Servlet容器,实现了Java Servlet和JavaServer Pages(JSP)规范。本文将深入探讨Tomcat 5的启动流程、目录结构以及配置详解。 1. **Tomcat...
### WebSocket的Java和Tomcat7使用详解 #### 一、WebSocket简介 随着互联网技术的不断发展,Web应用变得越来越复杂,传统的HTTP协议已经无法满足实时通信的需求。为了改善这一状况,HTML5引入了WebSocket协议,这...
《基于Tomcat7的Memcached会话管理器详解》 在现代Web应用中,会话管理是不可或缺的一部分,它确保用户在浏览多个页面时能够保持登录状态和其他个性化设置。然而,随着分布式系统的普及,单一服务器的会话管理方式...
**Tomcat目录结构配置详解** Tomcat是一款广泛使用的开源Java Servlet容器,它是Apache软件基金会的Jakarta项目的一部分。深入理解Tomcat的目录结构对于优化服务器性能、管理应用程序以及进行安全配置至关重要。...
【标题】"Tomcat-Redis-Session-Manager"是一个用于在Tomcat服务器中实现基于Redis的session管理解决方案。它使得Web应用的session数据能够在多个Tomcat实例之间共享,以实现负载均衡和高可用性。 【描述】这个项目...