一:前言:

最近支付后台登录一段时间后如果没有任何操作,总是需要重新登录才可以继续访问页面,出现这个问题的原因就是session超时,debug代码后发现session的超时时间是1800s。也就是说当1800秒内没有任何操作,session就会出现超时现象。那这个超时时间是如何设置的呢?然后该如何重新设置此超时时间呢?系统又如何判断session超时的呢?接下来就一一进行解答。

二:系统session超时时间如何默认的?

说明:获取session超时时间的方法为”request.getSession().getMaxInactiveInterval()",但是tomcat中设置超时时间的参数为“sessionTimeout”,那么他们是怎么联系起来的呢?

第一步:加载sessionTimeout参数。

1、项目运行初始化通过“@ConfigurationProperties”注解加载“org.springframework.boot.autoconfigure.web.ServerProperties”类。

//springBoot中默认的配置文件为"application.yml"或者"application.perties"文件,也就是说server是其中的一个配置参数。
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerPropertiesimplements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
//代码
}

2、上面类中“ServerProperties”继承自“EmbeddedServletContainerCustomizer”接口。重写customize方法,之后在此方法中“向上推”,即可找到“AbstractConfigurableEmbeddedServletContainer  ”类。

@Override
public void customize(ConfigurableEmbeddedServletContainer container) {//多个参数判断,如果在application中没配置的情况下都是nullif (getPort() != null) {container.setPort(getPort());}...//n多个参数判断,//以下的代码就是重点,因为是tomcat容器,所以以下条件为“真”,经过一系列的查找父类或者实现接口即可找到抽象类“AbstractConfigurableEmbeddedServletContainer”//public class TomcatEmbeddedServletContainerFactory extends AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware//public abstract class AbstractEmbeddedServletContainerFactory  extends AbstractConfigurableEmbeddedServletContainer  implements EmbeddedServletContainerFactory if (container instanceof TomcatEmbeddedServletContainerFactory) {getTomcat().customizeTomcat(this,(TomcatEmbeddedServletContainerFactory) container);}
//以上代码执行完成之后,实际上已经有对应的session所有的默认参数,之后通过下面方法,将所有参数放入对应的容器中。第3、4步就是设置过程container.addInitializers(new SessionConfiguringInitializer(this.session));
}

3、在“AbstractConfigurableEmbeddedServletContainer”类中终于可以找到“超时时间”的相关设置

//重要代码
//45行
private static final int DEFAULT_SESSION_TIMEOUT = (int) TimeUnit.MINUTES.toSeconds(30);
//66行
private int sessionTimeout = DEFAULT_SESSION_TIMEOUT;@Override
public void setSessionTimeout(int sessionTimeout) {this.sessionTimeout = sessionTimeout;
}
//171-188行
@Override
public void setSessionTimeout(int sessionTimeout, TimeUnit timeUnit) {Assert.notNull(timeUnit, "TimeUnit must not be null");this.sessionTimeout = (int) timeUnit.toSeconds(sessionTimeout);
}/*** Return the session timeout in seconds.* @return the timeout in seconds*/
public int getSessionTimeout() {return this.sessionTimeout;
}

4、执行第2步的”container.addInitializers(new SessionConfiguringInitializer(this.session))“加载所有的配置参数。

public static class Session {/*** Session timeout in seconds.*/private Integer timeout;public Integer getTimeout() {return this.timeout;}
//将session超时时间设置进来public void setTimeout(Integer sessionTimeout) {this.timeout = sessionTimeout;}

第二步:将上面的超时时间赋值给“MaxInactiveInterval”参数。

说明:既然上面tomcat需要的参数都已经加载完成,那么接下来就会运行tomcat,此处不做细讲,直接进入tomcat启动和加载参数说明。在“TomcatEmbeddedServletContainerFactory”类中的方法调用流程如下:

getEmbeddedServletContainer--》prepareContext--》configureContext--》configureSession--》getSessionTimeoutInMinutes。

1、调用configureSession设置tomcat的Session配置参数。

//以下代码
private void configureSession(Context context) {long sessionTimeout = getSessionTimeoutInMinutes();context.setSessionTimeout((int) sessionTimeout);Manager manager = context.getManager();if (manager == null) {manager = new StandardManager();//此处即为设置相应的参数的位置。之后会调用StandardContext类的setManger(Manager)方法,在setManger中会调用"manager.setContext(this)"context.setManager(manager);}
}
//计算超时时间为分钟(注意:此处会将之前的1800秒,转换为30分钟)。可以看出最终的时间结果是个整数的分钟类型,也就是说如果设置的超时时间(单位为秒)不是60的倍数,也会最终转换为60的倍数,并且最小超时时间设置的是60秒。
private long getSessionTimeoutInMinutes() {long sessionTimeout = getSessionTimeout();if (sessionTimeout > 0) {sessionTimeout = Math.max(TimeUnit.SECONDS.toMinutes(sessionTimeout), 1L);}return sessionTimeout;
}

2、最终将SessionTimeout赋值给MaxInactiveInterval。终于完成session超时时间设置。

//以下代码
@Override
public void setContext(Context context) {//省略其余设置代码,直接重新设置Session超时时间,此时又将上面的分钟单位转为秒。此时终于给Sesseion设置了默认超时时间。if (this.context != null) {setMaxInactiveInterval(this.context.getSessionTimeout() * 60);this.context.addPropertyChangeListener(this);}
}

三:如果自定义超时时间呢?

其实从上面的流程,已经不难看出,只需要在“org.springframework.boot.autoconfigure.web.ServerProperties”类中找到对应的Session参数,初始化让其加载上来即可完成设置。

/*** Get the session timeout.* @return the session timeout* @deprecated since 1.3.0 in favor of {@code session.timeout}.*/
@Deprecated
@DeprecatedConfigurationProperty(replacement = "server.session.timeout")
public Integer getSessionTimeout() {return this.session.getTimeout();
}

所以在application中配置“server.session.timeout“即可,参数类型为long类型,单位为”秒“。

四:运行程序是如何判断session超时的?

其实很简单:只需要在每次本次同一个sessionequest请求的时间,和之前的请求时间进行比较,发现两个值的差已经大于MaxInactiveInterval的值即可。

//判断是否超时
@Override
public boolean isValid() {//省略多个条件判断if (maxInactiveInterval > 0) {//判断此session空闲时间是否比maxInactiveInterval大,如果大的情况下,session就超时int timeIdle = (int) (getIdleTimeInternal() / 1000L);if (timeIdle >= maxInactiveInterval) {expire(true);}}return this.isValid;
}
//将上次访问时间和当前时间比较,拿到空闲时间值
@Override
public long getIdleTimeInternal() {long timeNow = System.currentTimeMillis();long timeIdle;if (LAST_ACCESS_AT_START) {timeIdle = timeNow - lastAccessedTime;} else {timeIdle = timeNow - thisAccessedTime;}return timeIdle;
}

说明:

所以为了保证session超时时间长点,可以在application配置文件中配置“server.session.timeout”参数即可,参数单位为“秒”,如果参数不是60的整数倍,会转换成60的整数倍(见二:系统如何设置超时时间、步骤二中的“1”中算法)。如不满一分钟,会转换为60秒。

扩展:

实际上也可以直接重写EmbeddedServletContainerCustomizer的customize方法进行赋值。

 @Beanpublic EmbeddedServletContainerCustomizer containerCustomizer(){return new EmbeddedServletContainerCustomizer() {@Overridepublic void customize(ConfigurableEmbeddedServletContainer container) {container.setSessionTimeout(600);//单位为S}};}

SpringBoot中Session超时原理说明相关推荐

  1. SpringBoot中事务执行原理分析(一)

    关联博文: SpringBoot中事务执行原理分析(一) SpringBoot中事务执行原理分析(二) SpringBoot中事务执行原理分析(三) SpringBoot中事务执行原理分析(四) Sp ...

  2. springboot设置session超时和session监听

    2.0版本以下设置session超时时间 1.  springboot 2.0版本以下配置session超时 1.1 application.properties配置文件: spring.sessio ...

  3. VB.NET工作笔记007---ASP.NET中Session超时一直不起作用

    技术交流QQ群[JAVA,.NET,BigData,AI]:170933152 最后发现是这个原因,在IIS中找到应用程序池,然后右边点击,详细设置,然后找到,进程模块中的 最大工作进程数,设置为1 ...

  4. asp.net中session的原理及应用

    Session简介丶特性 1.Session是一种Web会话中的常用状态之一. 2.Session提供了一种把信息保存在服务器内存中的方式.他能储存任何数据类型,包含自定义对象. 3.每个客户端的Se ...

  5. Shiro中Session过期页面跳转回登录页面处理问题

    Session超时的两种情况: shiro在管理session后,在session超时会进行跳转,这里有两种情况需要考虑,一种是ajax方式的请求超时,一种页面跳转请求的超时: 解决问题的思路:通过定 ...

  6. 单点登录,session超时, ajax链接处理

    1 错误场景 cas session 超时问题:XMLHttpRequest cannot loadhttps://www.hf.com:8443/cas/login?service=http%3A% ...

  7. (五)SSO之CAS框架单点登录, session超时, ajax链接处理

    1 错误场景 cas session 超时问题:XMLHttpRequest cannot loadhttps://www.hf.com:8443/cas/login?service=http%3A% ...

  8. java分布式会话redis_详解springboot中redis的使用和分布式session共享问题

    对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash.轮训.根据权重.随机等.不管对于哪一种负载均衡算法,由于Nginx对不同的请求分发到某一个Tomcat,Tomca ...

  9. SpringBoot中微服务技术中进程间通信原理

    在单体应用中,一个组件调用其它组组件时,是通过语言级的方法或者函数调用,而一个基于微服务的应用是运行于多个服务器上的分布式系统,每个服务实例是一个典型的进程.所以,如下图显示的,服务必须通过内部进程交 ...

  10. 在SpringBoot中使用Spring Session解决分布式会话共享问题

    在SpringBoot中使用Spring Session解决分布式会话共享问题 问题描述: 每次当重启服务器时,都会导致会员平台中已登录的用户掉线.这是因为每个用户的会话信息及状态都是由session ...

最新文章

  1. WFP在包含fwpmu.h头的时候出错
  2. torch_geometric 笔记:nn.ChebNet
  3. easypoi教程_SpringBoot图文教程17—上手就会 RestTemplate 使用指南
  4. ​从熵不变性看Attention的Scale操作
  5. LeetCode 1156. 单字符重复子串的最大长度
  6. 地区json文件_【小例子】使用jQuery实现省市区三级联动显示,附源码json文件
  7. 常用adb shell 命令
  8. php裁剪图片白边,php生成缩略图填充白边(等比缩略图方案)_PHP
  9. java io怎么学_Java IO 初学者 怎么都弄不出来
  10. 【转】前端进阶之路:如何高质量完成产品需求开发
  11. vs生成命令和属性的宏
  12. php动态网页设计(第2版),PHP动态网页设计(第2版)——使用PHP
  13. java modbus通讯协议_Modbus通 讯 协 议
  14. 《数据库系统概论》第五版 +学习笔记总目录
  15. virtualbox虚拟机linux共享文件夹,Virtualbox下linux虚拟机共享文件夹挂载
  16. 同是4G标准,TD和FDD谁更快?
  17. linux下这输入法切换大小写,Life With Arch:让Capslock成为输入法切换快捷键
  18. 【CodeForces 1253B --- Silly Mistake】
  19. nyist——ACM新生牛刀小试 Round#1题解
  20. 二叉树的前序,中序,后续(非递归版本)

热门文章

  1. 初装Windows11无法打开Windows安全中心主界面
  2. 服务器提供各种服务 包括文件服务器,服务器提供各种服务,包括文件服务器、邮件服务器、Web服务器等。...
  3. 计算机基础知识整理大全
  4. 【重点】commons-dbutils
  5. HFSS阵列天线仿真
  6. 计算机代数与数论pdf,计算机代数和数论(maple).pdf
  7. ppt设置外观样式_ppt怎么设置幻灯片的背景一样?
  8. 第一时间---Windows 7 with SP1中英文原版MSDN下载汇总---原汁原味
  9. win10需要开启系统打印机服务器,Win10系统开启和关闭打印机服务技巧
  10. quartus联合仿真步骤