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会话时间的半小时,并不是说会话创建后,... StandardSession是标准的HttpSession实现,同时它也实现了Session接口,用于Tomcat内部管理 StandardSessionFacade,类名已经指明它就是一个“门面
Tomcat集群 目录 Tomcat集群 1 一、环境介绍: 1 二、安装JDK 1 三、安装tomcat 2 四、安装nginx 2 ...6.4 修改tomcat中的server.xml文件 7 6.5放入项目文件 7 七、测试 7 八、关于tomcat的轮训模式 8
最新Apache2.2.11 + Tomcat 6.0.20 集群配置详解,版主亲测试,并且布署了真实的项目进行了测试,session 成功共享。欢迎大家下载。
孙卫琴《Tomcat与Java Web开发技术详解》培训讲义.rar 01__JavaWeb应用简介.pdf 02_Servlet技术.pdf 03_JSP技术.pdf 04_使用HTTP会话(Session).pdf 05_使用JavaBean.pdf 06_使用Servlet过滤器....
jar包:commons-pool2-2.4.2.jar、jedis-2.8.0.jar、tomcat-redis-session-manager-2.0.0.jar 二、配置Tomcat 多台Tomacat需要配置不同的端口号 /lib 将jar包存放到此位置 /conf/server.xml /conf/context.xml...
主要介绍了redission-tomcat快速实现从单机部署到多机部署详解,本文介绍一个基于redis的tomcat session管理开源项目:redission-tomcat,可无代码侵入式地快速实现session共享,需要的朋友可以参考下
注意:由于Redis配置对jar包和tomcat版本比较严格,请务必使用tomcat7和本文中提供的jar包。 下载地址: http://pan.baidu.com/s/1bO67Ky tomcat: tomcat1 localhost:8080 tomcat2 localhost:9080 nginx: ...
开始进行Web开发时,您可能在使用...容器(例如Tomcat、Jetty)包含Session的实现,当服务器重启之后,之前的登录状态会失效需要重新登录。 我们先从HTTP协议说起。HTTP协议有个特点,是无状态的,意味着请求与请求是没
14.8.7 设定内容类别的实现类SetContentTypeImpl.java 14.8.8 发布实现类EditImpl.java 14.9 编写内容管理系统的控制器类 14.9.1 登录控制器类LoginAction.java 14.9.2 注册控制器类RegeditAction.java 14.9.3 设定...
由于工作的需求,在使用中,需要搭建负载均衡,研究了Apache+Tomat负载均衡的方案,并且通过检索相关的文章,进行了比较发现,Apache负载负载均衡在使用的效率上,远远不如Nginx的效率高,因此决定使用Nginx来进行...
目录 常见WEB服务器 1 1、Nginx简介 2 2、反向代理Web服务器的“经纪人” 2 2.1反向代理初印象 2 2.2反向代理的作用 3 3、安装及配置 5 3.1下载 5 ...4.1.1 配置Tomcat的session共享可以有三种解决方案: 13
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识- 称为sessionid,如果已包含一个sessionid则说明以前已经为此客户端创建过session,服务器就...
1.2.5 支持集群功能的web服务器tomcat 21 1.2.6 开源数据库服务器之骄子mysql 23 1.2.7 功能强大的flv流媒体服务器red5 24 1.3 门户网站开发指导思想 26 1.4 ssh 2组合框架—门户网站开发之首选 28 1.4.1 mvc...
WEB服务器优化之Tomcat7性能调优 JVM概述 Java开发技术之(项目工程的日志管理) 数据库连接池原理详解 Java企业级框架之核心技术(反射) Java-Base64算法(创新_防止表单重复提交) 揭开springAOP神秘面纱之动态代理 ...
7.1 配置任意目录下的web应用程序 240 7.2 war文件 242 7.3 tomcat中servlet的另一种运行方式 244 7.4 与servlet配置相关的元素 247 7.4.1 [servlet]元素及其子元素 247 7.4.2 [servlet-mapping]元素及其子元素...
14.8.7 设定内容类别的实现类SetContentTypeImpl.java 14.8.8 发布实现类EditImpl.java 14.9 编写内容管理系统的控制器类 14.9.1 登录控制器类LoginAction.java 14.9.2 注册控制器类RegeditAction.java 14.9.3 设定...
7.1 配置任意目录下的web应用程序 240 7.2 war文件 242 7.3 tomcat中servlet的另一种运行方式 244 7.4 与servlet配置相关的元素 247 7.4.1 [servlet]元素及其子元素 247 7.4.2 [servlet-mapping]元素及其子元素...
14.8.7 设定内容类别的实现类SetContentTypeImpl.java 14.8.8 发布实现类EditImpl.java 14.9 编写内容管理系统的控制器类 14.9.1 登录控制器类LoginAction.java 14.9.2 注册控制器类RegeditAction.java 14.9.3 设定...
14.8.7 设定内容类别的实现类SetContentTypeImpl.java 14.8.8 发布实现类EditImpl.java 14.9 编写内容管理系统的控制器类 14.9.1 登录控制器类LoginAction.java 14.9.2 注册控制器类RegeditAction.java 14.9.3 设定...