From 0385bd41310ad13e888ec0d5eaa932b6f37fe65d Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Fri, 27 Apr 2018 13:16:17 -0700 Subject: [PATCH] Use spring.session.timeout for Spring Session timeout Fallback to server.servlet.session.timeout for backwards compatibility. Fixes gh-12906 --- .../session/SessionProperties.java | 28 +++++++++++---- .../SessionAutoConfigurationTests.java | 35 +++++++++++++------ .../appendix-application-properties.adoc | 1 + .../main/asciidoc/spring-boot-features.adoc | 3 +- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java index 3f09b6c8ee..f75e44cf3c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java @@ -17,13 +17,17 @@ package org.springframework.boot.autoconfigure.session; import java.time.Duration; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import javax.annotation.PostConstruct; + import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.convert.DurationUnit; import org.springframework.boot.web.servlet.DispatcherType; import org.springframework.boot.web.servlet.server.Session; import org.springframework.session.web.http.SessionRepositoryFilter; @@ -45,17 +49,25 @@ public class SessionProperties { private StoreType storeType; /** - * Session timeout. + * Session timeout. If a duration suffix is not specified, seconds will be used. */ - private final Duration timeout; + @DurationUnit(ChronoUnit.SECONDS) + private Duration timeout; private Servlet servlet = new Servlet(); + private final ServerProperties serverProperties; + public SessionProperties(ObjectProvider serverProperties) { - ServerProperties properties = serverProperties.getIfUnique(); - Session session = (properties == null ? null - : properties.getServlet().getSession()); - this.timeout = (session == null ? null : session.getTimeout()); + this.serverProperties = serverProperties.getIfUnique(); + } + + @PostConstruct + public void checkSessionTimeout() { + if (this.timeout == null && this.serverProperties != null) { + Session session = this.serverProperties.getServlet().getSession(); + this.timeout = (session == null ? null : session.getTimeout()); + } } public StoreType getStoreType() { @@ -83,6 +95,10 @@ public class SessionProperties { this.servlet = servlet; } + public void setTimeout(Duration timeout) { + this.timeout = timeout; + } + /** * Servlet-related properties. */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java index efd14bfbd7..419bd6da66 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.session; +import java.time.Duration; import java.util.Collections; import java.util.EnumSet; @@ -23,9 +24,10 @@ import javax.servlet.DispatcherType; import org.junit.Test; -import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; @@ -98,15 +100,23 @@ public class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurat } @Test - public void springSessionTimeoutIsNotAValidProperty() { - this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class) - .withPropertyValues("spring.session.timeout=3000").run((context) -> { - assertThat(context).hasFailed(); - assertThat(context).getFailure() - .isInstanceOf(BeanCreationException.class); - assertThat(context).getFailure() - .hasMessageContaining("Could not bind"); - }); + public void autoConfigWhenSpringSessionTimeoutIsSetShouldUseThat() { + this.contextRunner.withUserConfiguration(ServerPropertiesConfiguration.class, + SessionRepositoryConfiguration.class) + .withPropertyValues("server.servlet.session.timeout=1", + "spring.session.timeout=3").run((context) -> + assertThat(context.getBean(SessionProperties.class).getTimeout()) + .isEqualTo(Duration.ofSeconds(3))); + } + + @Test + public void autoConfigWhenSpringSessionTimeoutIsNotSetShouldUseServerSessionTimeout() { + this.contextRunner.withUserConfiguration(ServerPropertiesConfiguration.class, + SessionRepositoryConfiguration.class) + .withPropertyValues("server.servlet.session.timeout=3").run((context) -> { + assertThat(context.getBean(SessionProperties.class).getTimeout()) + .isEqualTo(Duration.ofSeconds(3)); + }); } @SuppressWarnings("unchecked") @@ -184,4 +194,9 @@ public class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurat } + @EnableConfigurationProperties(ServerProperties.class) + static class ServerPropertiesConfiguration { + + } + } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 70bdebbade..765cddb662 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -445,6 +445,7 @@ content into your application. Rather, pick only the properties that you need. # SPRING SESSION ({sc-spring-boot-autoconfigure}/session/SessionProperties.{sc-ext}[SessionProperties]) spring.session.store-type= # Session store type. + spring.session.timeout= # Session timeout. If a duration suffix is not specified, seconds will be used. spring.session.servlet.filter-order=-2147483598 # Session repository filter order. spring.session.servlet.filter-dispatcher-types=async,error,request # Session repository filter dispatcher types. diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 575277664a..38a2fe917e 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -6014,7 +6014,8 @@ the name of the table for the JDBC store, as shown in the following example: spring.session.jdbc.table-name=SESSIONS ---- - +For setting the timeout of the session you can use the `spring.session.timeout` property. +If that property is not set, the auto-configuration will fallback to the value of `server.servlet.session.timeout`. [[boot-features-jmx]] == Monitoring and Management over JMX