0

0

详解SpringBoot中Session超时问题原因

巴扎黑

巴扎黑

发布时间:2018-05-10 13:49:59

|

5993人浏览过

|

来源于php中文网

原创

本篇文章主要介绍了详解springbootsession超时原理说明,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一:前言:

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

Designs.ai
Designs.ai

AI设计工具

下载

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
   }
  };
 }

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
如何配置Tomcat环境变量
如何配置Tomcat环境变量

配置Tomcat环境变量需要在系统中添加CATALINA_HOME变量,并将Tomcat的安装路径添加到PATH变量中。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

114

2023.10.26

idea如何集成Tomcat
idea如何集成Tomcat

idea集成Tomcat的步骤:1、添加Tomcat服务器配置;2、配置项目部署;3、运行Tomcat服务器;4、访问项目;5、注意事项;6、关闭Tomcat服务器。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

169

2024.02.23

怎么查看Tomcat源代码
怎么查看Tomcat源代码

查看Tomcat源代码的步骤:1、下载Tomcat源代码;2、在IDEA中导入Tomcat源代码;3、查看源代码;4、理解Tomcat的工作原理;5、参与社区和贡献;6、注意事项;7、持续学习和更新;8、使用工具和插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

97

2024.02.23

常见的tomcat漏洞有哪些
常见的tomcat漏洞有哪些

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

163

2024.02.23

tomcat日志乱码怎么解决
tomcat日志乱码怎么解决

tomcat日志乱码的解决办法:1、修改tomcat的日志编码设置;2、检查ide的编码设置;3、检查操作系统的编码设置;4、使用过滤器处理日志;5、检查外部系统的编码设置;6、检查文件编码方式等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

151

2024.02.23

weblogic和tomcat有哪些区别
weblogic和tomcat有哪些区别

weblogic和tomcat的区别:1、功能;2、性能;3、规模;4、价格;5、安全性;6、配置和管理;7、社区支持;8、集成能力;9、升级和更新;10、可靠性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2024.02.23

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

233

2024.02.23

tomcat启动闪退怎么解决
tomcat启动闪退怎么解决

tomcat启动闪退的解决办法:1、检查java环境;2、检查环境变量配置;3、检查端口被占用;4、检查配置文件编码;5、检查启动时需要的配置文件;6、检查相关文件是否丢失;7、检查防火墙和杀毒软件设置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

161

2024.02.23

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Redis6入门到精通超详细教程
Redis6入门到精通超详细教程

共47课时 | 5.3万人学习

Laravel 5.8 中文文档手册
Laravel 5.8 中文文档手册

共74课时 | 88.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号