使用 Spring Boot 和嵌入式 Tomcat 启用会话持久性

Posted

技术标签:

【中文标题】使用 Spring Boot 和嵌入式 Tomcat 启用会话持久性【英文标题】:Enable session persistence with Spring Boot and embedded Tomcat 【发布时间】:2015-04-13 04:08:43 【问题描述】:

我正在开发一个带有 Spring Boot 和 Spring Security 的应用程序,方法是在 Eclipse 中使用嵌入式 Tomcat 启动 Application 类。每次我重新启动服务器时,我的会话都会消失,我必须重新登录,这变得很烦人。

是否可以在服务器重启之间保持会话?

我在 *** 上看到了另一个问题,有人问相反的问题,这让我认为这实际上应该是开箱即用的:

How to disable Tomact session persistence in Spring Boot via Manager pathname?

我正在使用 Gradle 运行 Spring Boot 1.2.1。

顺便说一句,我知道 Spring Loaded,但有时服务器重启是不可避免的。

【问题讨论】:

您是否查看过这些帖子:JDBC Session Persistence & FilterInvocationInterceptor Bean ? 还要确保您在会话中放入的所有内容都是可序列化的 【参考方案1】:

根据 Spring,这将在 1.3.0.M2 并最终在 1.3.0.RELEASE

中修复

那么您所要做的就是将以下行添加到您的 application.properties 文件中。

server.session.persistent=true

在最近的 Spring 版本中,这已被弃用并替换为:

server.servlet.session.persistent=true

参考https://github.com/spring-projects/spring-boot/issues/2490

更新 Tomcat、Jetty 和 Undertow 以序列化会话数据,当 应用程序停止并在应用程序时再次加载它 重新启动。

持久会话可选择加入;通过设置persistentSession 在 ConfigurableEmbeddedServletContainer 上或使用属性 server.session.persistent=true.

修复 gh-2490

【讨论】:

是的,这个问题现在已经修复了——还值得一提的是 devtools 默认启用了这个标志。 我有这个,但在服务器重启后我仍然丢失了我的 Spring 身份验证。 :( 如果您启用了 spring security,请确保您放入 SecurityContext 的任何自定义对象都是可序列化的,否则恢复的 session 将被 spring security 视为无效。【参考方案2】:

这是我自己想出来的。每次启动应用程序时,Spring 都会在 /tmp 中为 Tomcat 的基本目录生成一个新的随机临时目录(例如 /tmp/tomcat.5990562997404648887.8080)。由于每次启动时使用不同的文件夹,Tomcat 无法恢复会话。

这可以通过使用server.tomcat.basedir=/tmp 设置您自己的基本目录来解决。但是,我不认为这是一个修复,因为它需要设置一个操作系统特定的目录,所以我打开了一个关于这个的错误:https://github.com/spring-projects/spring-boot/issues/2490

【讨论】:

【参考方案3】:

我通过使用 Redis 来持久化会话信息解决了这个问题。

您需要做的就是在 application.yml 文件中指定一些选项:

server:
  servlet:
    session:
      persistent: true
spring:
  session:
    store-type: redis
  redis:
    host: localhost
    port: 6379
 ...

build.gradle

    plugins 
       id 'java'
       id 'io.spring.dependency-management' version '1.0.6.RELEASE'
       id 'org.springframework.boot' version '2.1.3.RELEASE'
   
    ...
    // Spring Framework
    compile(
            'org.springframework.boot:spring-boot-starter-web',
            'org.springframework.boot:spring-boot-starter-data-jpa',
            'org.springframework.data:spring-data-redis',
            'org.springframework.boot:spring-boot-starter-security'
    )
    ...

与 Spring Boot 2.1.3 完美搭配

【讨论】:

你好,为什么需要 jpa? @Tama 对于您不需要的会话持久性,这是我项目中的示例文件。我需要它来支持数据库。

以上是关于使用 Spring Boot 和嵌入式 Tomcat 启用会话持久性的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 使用 jsp视图(巨坑)

如何避免使用 Spring-Boot 下载嵌入式 MongoDb

通过spring boot构建solr查询实例

Spring boot Artemis 嵌入式代理行为

如何使用Spring Boot和嵌入式Tomcat配置此属性?

如何使用 Spring Boot 和嵌入式 Tomcat 配置此属性?