文章目录

  • 1. 定义
  • 2. 和Cookie比较
  • 3. 图解
  • 4. 源码解析(Java)
  • 5. 总结

1. 定义

Session在计算机中,尤其是网络应用中,被称为“会话控制”。

Session对象可以存储用户在程序中的一些数据,用户在系统中不同的web页面之间进行跳转时,存储在Session中的数据不会丢失。

当用户请求来自web页面时,如果该用户还没有会话,web服务器就会创建一个新的Session对象。当会话过期或者被放弃后,服务器将终止该会话。

2. 和Cookie比较

Session和Cookie都可以保存用户数据,但是Session是保存在服务端Cookie是保存在客户的浏览器中。

电脑桌面端应用APP应用不保存Cookie。

Session的实现需要依赖于Cookie,当服务端创建Session后,会返回一个JSESSIONID存到Cookie中,下次再请求时,请求头中携带的Cookie会将JSESSIONID一并带回到服务端,这样服务端就可以找到对应的Session对象。

3. 图解

Session是在servlet中遇到request.getSession()时创建的;JSP本质就是一个servlet,将JSP编译后得到的servlet中,就会有request.getSession()代码,所以访问JSP也会创建Session。

4. 源码解析(Java)

随便在一个接口中加入以下代码:

// 在任意地方获取当前请求的request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 利用request获取session
HttpSession session = request.getSession();

springboot使用内置tomcat启动时,request对象是org.apache.catalina.connector.RequestFacade的实例。

首先进入request.getSession()方法:

@Override
public HttpSession getSession() {// 对request的非空判断if (request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));}// 默认传参truereturn getSession(true);
}

进入getSession(true)方法:

/*** @param create 当session不存在时,是否新创建session*/
@Override
public HttpSession getSession(boolean create) {// 对request的非空判断if (request == null) {throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));}// 包保护特殊处理逻辑if (SecurityUtil.isPackageProtectionEnabled()){return AccessController.doPrivileged(new GetSessionPrivilegedAction(create));} else {return request.getSession(create);}
}

此处request属于org.apache.catalina.connector.Request类,进入request.getSession(create)方法:

@Override
public HttpSession getSession(boolean create) {// 真正获取Session的方法Session session = doGetSession(create);if (session == null) {return null;}// 获取HttpSessionreturn session.getSession();
}

进入doGetSession(create)方法:

protected Session doGetSession(boolean create) {// tomcat上下文Context context = getContext();if (context == null) {return null;}// 如果session不为空且session对象是无效的,则置session为nullif ((session != null) && !session.isValid()) {session = null;}// 如果session不为空,且是有效的session,则直接返回sessionif (session != null) {return session;}// 获取上下文中管理器对象Manager manager = context.getManager();// 管理器对象为空说明不支持Session,直接返回nullif (manager == null) {return null;}// 从Cookie中解析到的JSESSIONID如果不为空if (requestedSessionId != null) {try {// 根据SessionId从管理器对象中查找对应的Session对象session = manager.findSession(requestedSessionId);} catch (IOException e) {// 出错打印日志if (log.isDebugEnabled()) {log.debug(sm.getString("request.session.failed", requestedSessionId, e.getMessage()), e);} else {log.info(sm.getString("request.session.failed", requestedSessionId, e.getMessage()));}session = null;}// 获取出来的session对象不为空且session已失效,则将session置为nullif ((session != null) && !session.isValid()) {session = null;}// session对象不为空且session有效if (session != null) {// 更新session中的最后访问时间为当前时间session.access();// 返回sessionreturn session;}}// 如果请求中未传递sessionId且create参数为false,则表示当前请求不存在对应session对象时不新创建if (!create) {return null;}// 有效的会话跟踪模式是否包含Cookie模式boolean trackModesIncludesCookie =context.getServletContext().getEffectiveSessionTrackingModes().contains(SessionTrackingMode.COOKIE);// 支持Cookie且response已经被提交(response不能再向缓冲区写入任何东西)则直接抛出异常if (trackModesIncludesCookie && response.getResponse().isCommitted()) {throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));}// 获取sessionIdString sessionId = getRequestedSessionId();if (requestedSessionSSL) {} else if (("/".equals(context.getSessionCookiePath()) && isRequestedSessionIdFromCookie())) { // 如果sessioncookie的path为/,且sessionId来自于cookieif (context.getValidateClientProvidedNewSessionId()) {boolean found = false;// 获取tomcat中当前Host下所有的Container,在每个container中寻找sessionId对应的session,如果存在对应的session,则标记为foundfor (Container container : getHost().findChildren()) {Manager m = ((Context) container).getManager();if (m != null) {try {if (m.findSession(sessionId) != null) {found = true;break;}} catch (IOException e) {// Ignore. Problems with this manager will be// handled elsewhere.}}}// 如果都没有,则将sessionId置空if (!found) {sessionId = null;}}} else {sessionId = null;}// 创建session对象session = manager.createSession(sessionId);// 基于session对象创建一个session cookieif (session != null && trackModesIncludesCookie) {// 创建Cookie对象,并设置MaxAge、Comment、Domain、Secure、HttpOnly、Path参数Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie(context, session.getIdInternal(), isSecure());// 向response中增加Set-Cookie响应头response.addSessionCookieInternal(cookie);}if (session == null) {return null;}// 设置访问时间为当前时间session.access();return session;
}

判断session是否失效的session.isValid()方法:

@Override
public boolean isValid() {if (!this.isValid) {return false;}if (this.expiring) {return true;}if (ACTIVITY_CHECK && accessCount.get() > 0) {return true;}// 最大存活时间是否大于0if (maxInactiveInterval > 0) {// 获取存活时间(s)int timeIdle = (int) (getIdleTimeInternal() / 1000L);// 存活时间超过最大存活时间则使其失效if (timeIdle >= maxInactiveInterval) {expire(true);}}return this.isValid;
}

5. 总结

Session是一项会话存储技术,它的实现需要Cookie的配合。服务端根据请求中Cookie携带的JSESSIONID参数寻找对应的Session对象。

第一次请求没有携带JSESSIONID或者JSESSIONID对应的Session对象已经失效或者不存在,则服务端创建新的Session,并将JSESSIONID添加到响应头中,浏览器端接收到响应后,设置Cookie中的JSESSIONID参数。

Session的作用及原理相关推荐

  1. Cookie和Session的作用,区别和各自的应用范围,Session工作原理

    Cookie和Session的作用与区别 Session用于保存每个用户的专用信息. 每个客户端用户访问时,服务器都为每个用户分配一个唯一的会话ID(Session ID) . 她的生存期是用户持续请 ...

  2. Cookie和Session的作用和工作原理

    一.Cookie详解 (1)简介 因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现.在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料 ...

  3. volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...

  4. Bundler 的作用及原理

    Bundler 的作用及原理 翻译 · yesmeck · Created at one year ago · Last by teacafe2000 Replied at one year ago  ...

  5. JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架...

    1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...

  6. Batch Normalization的作用及原理

    目录 声明 BN是什么[1] 为什么提出BN[1, 2] BN的作用及原理 加速训练,提高收敛速度[1] 缓解梯度消失(梯度爆炸)[3] 缓解过拟合[4] 其他相关问题 BN和激活函数的顺序问题[5] ...

  7. 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

    1 LES BX, DWORD PTR DS:_OSTCBCur ;OSTCBCur->OSTCBStkPtr = SS:SP!!! 2 MOV ES:[BX+2], SS ;将当前SS(栈的基 ...

  8. python super()方法的作用_详解python的super()的作用和原理

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...

  9. 主从复制面试之作用和原理

    主从复制面试之作用和原理 有些同学连集群和主从都分不清楚的,这里我说一下他们最本质的区别,其实也就是data-sharing和nothing-sharing的区别.集群是共享存储的.主从复制中没有任何 ...

最新文章

  1. 整理对应_JSP第二版课后习题答案【侵权联系我删除】
  2. AngularJS学习日记(四)Service和Provider
  3. 2017年9月2日普级组T2 跳格子
  4. python画图比赛_Python选修课第二届Turtle绘图大赛
  5. Linux-MySQL基本命令-SQL语句
  6. python内存管理机制错误_Python内存管理机制和垃圾回收机制的简单理解
  7. 精确的硬盘整数分区方法
  8. 计算机发送到桌面快捷方式,win10电脑没有发送到桌面快捷方式选项的详细恢复步骤...
  9. ARMv8-A TrustZone概述
  10. 使用PS制作毛玻璃效果
  11. 英语基础语法-语态(被动语态Be done)
  12. 投影仪家用推荐最新?投影仪什么牌子性价比比较高
  13. java论文word_JAVA课程实践报告 基于web的点餐系统毕业设计word格式
  14. 蔡高厅高等数学21-连续函数闭区间的性质(最大最小值定理、有界性定理、零值点定理、介值定理、推论)
  15. python程序设计思维导图_程序设计 思维导图
  16. linux 黑屏后死机,如何修复各种各样的黑屏死机
  17. 视频像素数据_从摄像头到驱动
  18. python画图小动物_如何用python画简单的动物
  19. ckeditor 工具栏配置
  20. R语言如何向向量中追加一个元素?

热门文章

  1. 批量修改图片尺寸(适用于4:3和16:9的图片)
  2. 湖南福米科技Java开发岗暑期实习面经
  3. 你知道如何写一个框架吗?详细步骤放送(上)
  4. php不通过js链接workeman,workerman 403毛病缘由与解决方法_PHP开发框架教程,workerman...
  5. 死锁的概念以及发生死锁的缘由
  6. 动态路由协议简单理解
  7. windows driver - DeviceIoControl 用法
  8. 数据库系统原理课后练习题(期末复习题目附答案)
  9. TKmybatis的使用,MyBatis的Mapper接口、Example方法
  10. vue打包部署服务器,背景图片显示空白