一:前言:

最近支付后台登录一段时间后如果没有任何操作,总是需要重新登录才可以继续访问页面,出现这个问题的原因就是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 ServerProperties

implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {

//代码

}

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

@Override

public void customize(ConfigurableEmbeddedServletContainer container) {

//多个参数判断,如果在application中没配置的情况下都是null

if (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方法进行赋值。

@Bean

public EmbeddedServletContainerCustomizer containerCustomizer(){

return new EmbeddedServletContainerCustomizer() {

@Override

public void customize(ConfigurableEmbeddedServletContainer container) {

container.setSessionTimeout(600);//单位为S

}

};

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

java session超时判断_详解SpringBoot中Session超时原理说明相关推荐

  1. java xml快捷注释_详解SpringBoot 快速整合Mybatis(去XML化+注解进阶)

    序言:使用MyBatis3提供的注解可以逐步取代XML,例如使用@Select注解直接编写SQL完成数据查询,使用@SelectProvider高级注解还可以编写动态SQL,以应对复杂的业务需求. 一 ...

  2. java h5模板引擎_详解SpringBoot+Thymeleaf 基于HTML5的现代模板引擎

    序言: Thymeleaf 是Java服务端的模板引擎,与传统的JSP不同,前者可以使用浏览器直接打开,因为可以忽略掉拓展属性,相当于打开原生页面,给前端人员也带来一定的便利.如果你已经厌倦了JSP+ ...

  3. 详解JSP 中Spring工作原理及其作用

    详解JSP 中Spring工作原理及其作用 1.springmvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作. 2.Dispat ...

  4. java 配置文件的路径_详解java配置文件的路径问题

    详解java配置文件的路径问题 详解java配置文件的路径问题 各种语言都有自己所支持的配置文件,配置文件中有很多变量是经常改变的.不将程序中的各种变量写死,这样能更方便地脱离程序本身去修改相关变量设 ...

  5. java新建一个女朋友_详解java创建一个女朋友类(对象啥的new一个就是)==建造者模式,一键重写...

    创建一个女朋友,她有很多的属性,比如:性别,年龄,身高,体重,类型等等,虽然每个女朋友都有这些属性,但是每个人找女朋友的要求都是不一样的,有的人喜欢男的,有的人喜欢女的,有的喜欢胖的,不同的人可以根据 ...

  6. java 标量替换_详解jvm中的标量替换

    概述 通常在java中创建一个对象,大家都认为是在堆中创建. 在jdk6开始有逃逸分析,标量替换等技术,关于在堆中创建对象不再绝对. 关于标量替换,通过以下几点进行概述: 逃逸分析 标量替换是什么 测 ...

  7. redis watch使用场景_详解redis中的锁以及使用场景

    分布式锁 什么是分布式锁? 分布式锁是控制分布式系统之间同步访问共享资源的一种方式. 为什么要使用分布式锁? ​ 为了保证共享资源的数据一致性. 什么场景下使用分布式锁? ​ 数据重要且要保证一致性 ...

  8. python操作目录_详解python中的文件与目录操作

    详解python中的文件与目录操作 一 获得当前路径 1.代码1 >>>import os >>>print('Current directory is ',os. ...

  9. pythonnamedtuple定义类型_详解Python中namedtuple的使用

    namedtuple是Python中存储数据类型,比较常见的数据类型还有有list和tuple数据类型.相比于list,tuple中的元素不可修改,在映射中可以当键使用. namedtuple: na ...

  10. python3 yield 大文件_详解Python3中yield生成器的用法

    任何使用yield的函数都称之为生成器,如: def count(n): while n > 0: yield n #生成值:n n -= 1 另外一种说法:生成器就是一个返回迭代器的函数,与普 ...

最新文章

  1. Ubuntu在终端执行命令时出现的错误
  2. matlab vco,MATLAB锁相环仿真程序求解
  3. php 通过相对或得绝对,相对路径与绝对路径的了解与深入
  4. linuxoracle静默安装应答文件修改_Oracle 19c的examples静默安装
  5. 你真的会使用Eclipse的debug吗?
  6. 计算实际例子_【科普】机器学习的核心计算:距离+统计?
  7. WebRTC 将一统实时音视频天下?
  8. spring 自定义注解及使用
  9. 路由器当ap用虚拟服务器不能用,解决用TPLINK路由器配置模拟AP时Internet连接共享是空白的问题...
  10. 揭开人创造思维之谜:浴缸和床最易引发灵感
  11. 跨境电商“独立站”新风口丨从0-1答疑解惑篇
  12. [无人机学习]无人机学习概论
  13. 盛大搅局手游市场:引入日系卡牌游戏_0
  14. 如何正确使用HTTP代理?
  15. 灌南县计算机中专学校,江苏省灌南中等专业学校2021年招生简章
  16. c++校招面试题目总结
  17. 【计算机网络】第三部分 数据链路层(13) 有线局域网:以太网
  18. Ubuntu16.04安装软件提示E: Encountered a section with no Package: header错误
  19. python输出十六进制大小写_Python学习任务2十六进制和大小写转换
  20. 第5章 - 二阶多智能体系统的协同控制 --> 连续时间含时延系统一致性

热门文章

  1. Go 语言圣经-习题汇总(Go 程序设计语言/The Go Programming Language)
  2. MindManager思维导图 PRDBRD写作方法与技巧 产品规划模板下载
  3. 三角网导线平差实例_三角网闭合导线平差计算表0
  4. java如何删除文件夹_Java如何删除文件夹和子文件夹
  5. 禅道的下载和安装教程(Linux版)
  6. hive3.1.2的下载及安装
  7. step13. ubuntu18.04下载安装配置Hive(转)
  8. Python 文本滚动播放
  9. 21_08_17王道计算机考研 数据结构(二)
  10. Android8.1根据app名字调用显示app的属性页(App info)