Update documentation for 2.0

Closes gh-199
Closes gh-826
Closes gh-878
Closes gh-893
This commit is contained in:
Vedran Pavic
2018-01-05 18:34:12 +01:00
committed by Rob Winch
parent 2f49a8ac25
commit 45807998f6
17 changed files with 477 additions and 120 deletions

View File

@@ -6,20 +6,20 @@ dependencies {
testCompile project(':spring-session-data-redis')
testCompile project(':spring-session-hazelcast')
testCompile project(':spring-session-jdbc')
testCompile "org.springframework:spring-jdbc"
testCompile "org.springframework:spring-messaging"
testCompile "org.springframework:spring-webmvc"
testCompile "org.springframework:spring-websocket"
testCompile "org.springframework.security:spring-security-config"
testCompile "org.springframework.security:spring-security-web"
testCompile "org.springframework.security:spring-security-test"
testCompile "junit:junit"
testCompile "org.mockito:mockito-core"
testCompile "org.springframework:spring-test"
testCompile "org.assertj:assertj-core"
testCompile "com.hazelcast:hazelcast"
testCompile "io.lettuce:lettuce-core"
testCompile "javax.servlet:javax.servlet-api"
testCompile 'org.springframework:spring-jdbc'
testCompile 'org.springframework:spring-messaging'
testCompile 'org.springframework:spring-webmvc'
testCompile 'org.springframework:spring-websocket'
testCompile 'org.springframework.security:spring-security-config'
testCompile 'org.springframework.security:spring-security-web'
testCompile 'org.springframework.security:spring-security-test'
testCompile 'junit:junit'
testCompile 'org.mockito:mockito-core'
testCompile 'org.springframework:spring-test'
testCompile 'org.assertj:assertj-core'
testCompile 'com.hazelcast:hazelcast'
testCompile 'io.lettuce:lettuce-core'
testCompile 'javax.servlet:javax.servlet-api'
}
def versions = dependencyManagement.managedVersions
@@ -27,19 +27,22 @@ def versions = dependencyManagement.managedVersions
asciidoctor {
def ghTag = snapshotBuild ? 'master' : project.version
def ghUrl = "https://github.com/spring-projects/spring-session/tree/$ghTag"
attributes 'version-snapshot': snapshotBuild,
attributes 'docs-itest-dir': "$rootProject.projectDir.path/docs/src/integration-test/java/",
'docs-test-dir': "$rootProject.projectDir.path/docs/src/test/java/",
'docs-test-resources-dir': "$rootProject.projectDir.path/docs/src/test/resources/",
'download-url': "https://github.com/spring-projects/spring-session/archive/${ghTag}.zip",
'gh-samples-url': "$ghUrl/samples/",
'gh-url': ghUrl,
'hazelcast-version': versions['com.hazelcast:hazelcast'],
'lettuce-version': versions['io.lettuce:lettuce-core'],
'samples-dir': "$rootProject.projectDir.path/samples/",
'session-jdbc-main-resources-dir': "${project(':spring-session-jdbc').projectDir.path}/src/main/resources/",
'spring-data-redis-version': versions['org.springframework.data:spring-data-redis'],
'spring-framework-version': versions['org.springframework:spring-core'],
'spring-security-version': versions['org.springframework.security:spring-security-core'],
'spring-session-version': project.version,
'version-milestone': milestoneBuild,
'version-release': releaseBuild,
'gh-url': ghUrl,
'gh-samples-url': "$ghUrl/samples/",
'download-url' : "https://github.com/spring-projects/spring-session/archive/${ghTag}.zip",
'spring-session-version' : version,
'spring-version' : versions['org.springframework:spring-core'],
'lettuce-version' : versions['io.lettuce:lettuce-core'],
'hazelcast-version' : versions['com.hazelcast:hazelcast'],
'docs-itest-dir' : rootProject.projectDir.path + '/docs/src/integration-test/java/',
'docs-test-dir' : rootProject.projectDir.path + '/docs/src/test/java/',
'docs-test-resources-dir' : rootProject.projectDir.path + '/docs/src/test/resources/',
'samples-dir' : rootProject.projectDir.path + '/samples/',
'session-jdbc-main-resources-dir' : project(':spring-session-jdbc').projectDir.path + '/src/main/resources/'
'version-snapshot': snapshotBuild
}

View File

@@ -108,7 +108,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====

View File

@@ -54,7 +54,7 @@ spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@p
spring.session.jdbc.table-name=SPRING_SESSION # Name of database table used to store sessions.
----
For more information, refer to http://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] portion of the Spring Boot documentation.
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] portion of the Spring Boot documentation.
[[httpsession-jdbc-boot-configuration]]
== Configuring the DataSource
@@ -70,7 +70,7 @@ spring.datasource.username=myapp
spring.datasource.password=secret
----
For more information, refer to http://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-configure-datasource[Configure a DataSource] portion of the Spring Boot documentation.
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-configure-datasource[Configure a DataSource] portion of the Spring Boot documentation.
[[httpsession-jdbc-boot-servlet-configuration]]
== Servlet Container Initialization
@@ -120,7 +120,7 @@ Spring Session replaces the `HttpSession` with an implementation that is backed
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into H2 database.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL)

View File

@@ -51,7 +51,7 @@ spring.session.redis.flush-mode= # Sessions flush mode.
spring.session.redis.namespace= # Namespace for keys used to store sessions.
----
For more information, refer to http://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] portion of the Spring Boot documentation.
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] portion of the Spring Boot documentation.
[[boot-redis-configuration]]
== Configuring the Redis Connection
@@ -67,7 +67,7 @@ spring.redis.password=secret
spring.redis.port=6379
----
For more information, refer to http://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-connecting-to-redis[Connecting to Redis] portion of the Spring Boot documentation.
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-connecting-to-redis[Connecting to Redis] portion of the Spring Boot documentation.
[[boot-servlet-configuration]]
== Servlet Container Initialization
@@ -91,7 +91,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
@@ -122,13 +122,13 @@ Spring Session replaces the `HttpSession` with an implementation that is backed
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Redis.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for http://redis.io/topics/quickstart[installing redis-cli].
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:

View File

@@ -83,7 +83,7 @@ server.session.timeout=60
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====

View File

@@ -70,7 +70,7 @@ spring:
port: 6397
----
For more information, refer to http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-connecting-to-redis[Connecting to Redis] portion of the Spring Boot documentation.
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-connecting-to-redis[Connecting to Redis] portion of the Spring Boot documentation.
[[grails3-sample]]
== Grails 3 Sample Application
@@ -84,7 +84,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
@@ -115,13 +115,13 @@ Spring Session replaces the `HttpSession` with an implementation that is backed
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Redis.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for http://redis.io/topics/quickstart[installing redis-cli].
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:

View File

@@ -78,7 +78,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====

View File

@@ -26,7 +26,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -85,7 +85,7 @@ In this instance Spring Session is backed by Hazelcast.
Spring Session provides `PrincipalNameExtractor` for this purpose.
<3> We create a `HazelcastInstance` that connects Spring Session to Hazelcast.
By default, an embedded instance of Hazelcast is started and connected to by the application.
For more information on configuring Hazelcast, refer to the http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#hazelcast-configuration[reference documentation].
For more information on configuring Hazelcast, refer to the http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[reference documentation].
== Servlet Container Initialization
@@ -130,7 +130,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
====
Hazelcast will run in embedded mode with your application by default, but if you want to connect
to a stand alone instance instead, you can configure it by following the instructions in the
http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#hazelcast-configuration[reference documentation].
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[reference documentation].
====
----
@@ -157,13 +157,13 @@ Spring Session replaces the `HttpSession` with an implementation that is backed
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Hazelcast.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
=== Interact with the data store
If you like, you can remove the session using http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#hazelcast-java-client[a Java client],
http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#other-client-implementations[one of the other clients], or the
http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#management-center[management center].
If you like, you can remove the session using http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-java-client[a Java client],
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#other-client-implementations[one of the other clients], or the
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#management-center[management center].
==== Using the console
@@ -172,7 +172,7 @@ For example, using the management center console after connecting to your Hazelc
default> ns spring:session:sessions
spring:session:sessions> m.clear
TIP: The Hazelcast documentation has instructions for http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#executing-console-commands[the console].
TIP: The Hazelcast documentation has instructions for http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#executing-console-commands[the console].
Alternatively, you can also delete the explicit key. Enter the following into the console ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:
@@ -183,7 +183,7 @@ Now visit the application at http://localhost:8080/ and observe that we are no l
==== Using the REST API
As described in the other clients section of the documentation, there is a
http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#rest-client[REST API]
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#rest-client[REST API]
provided by the Hazelcast node(s).
For example, you could delete an individual key as follows (replacing `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie):

View File

@@ -26,7 +26,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -85,7 +85,7 @@ In this instance Spring Session is backed by a relational database.
We configure the H2 database to create database tables using the SQL script which is included in Spring Session.
<3> We create a `transactionManager` that manages transactions for previously configured `dataSource`.
For additional information on how to configure data access related concerns, please refer to the http://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-data-tier.html[Spring Framework Reference Documentation].
For additional information on how to configure data access related concerns, please refer to the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/data-access.html[Spring Framework Reference Documentation].
== Java Servlet Container Initialization
@@ -145,7 +145,7 @@ include::{samples-dir}javaconfig/jdbc/src/main/java/sample/SessionServlet.java[t
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in H2 database.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL)

View File

@@ -31,7 +31,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -88,7 +88,7 @@ The filter is what is in charge of replacing the `HttpSession` implementation to
In this instance Spring Session is backed by Redis.
<2> We create a `RedisConnectionFactory` that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379)
For more information on configuring Spring Data Redis, refer to the http://docs.spring.io/spring-data/data-redis/docs/current/reference/html/[reference documentation].
For more information on configuring Spring Data Redis, refer to the https://docs.spring.io/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation].
== Java Servlet Container Initialization
@@ -125,7 +125,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
@@ -157,13 +157,13 @@ include::{samples-dir}javaconfig/redis/src/main/java/sample/SessionServlet.java[
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in Redis.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for http://redis.io/topics/quickstart[installing redis-cli].
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:

View File

@@ -31,7 +31,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -88,7 +88,7 @@ The filter is what is in charge of replacing the `HttpSession` implementation to
In this instance Spring Session is backed by Redis.
<2> We create a `RedisConnectionFactory` that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379)
For more information on configuring Spring Data Redis, refer to the http://docs.spring.io/spring-data/data-redis/docs/current/reference/html/[reference documentation].
For more information on configuring Spring Data Redis, refer to the https://docs.spring.io/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation].
<3> We customize Spring Session's HttpSession integration to use HTTP headers to convey the current session information instead of cookies.
== Servlet Container Initialization
@@ -126,7 +126,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
@@ -209,7 +209,7 @@ Now remove the session using redis-cli. For example, on a Linux based system you
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for http://redis.io/topics/quickstart[installing redis-cli].
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:

View File

@@ -32,7 +32,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -87,7 +87,7 @@ The filter is what is in charge of replacing the `HttpSession` implementation to
In this instance Spring Session is backed by Redis.
<2> We create a `RedisConnectionFactory` that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379)
For more information on configuring Spring Data Redis, refer to the http://docs.spring.io/spring-data/data-redis/docs/current/reference/html/[reference documentation].
For more information on configuring Spring Data Redis, refer to the https://docs.spring.io/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation].
== Servlet Container Initialization
@@ -130,7 +130,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
@@ -159,13 +159,13 @@ Spring Session replaces the `HttpSession` with an implementation that is backed
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Redis.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for http://redis.io/topics/quickstart[installing redis-cli].
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:

View File

@@ -26,7 +26,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -87,7 +87,7 @@ In this instance Spring Session is backed by a relational database.
We configure the H2 database to create database tables using the SQL script which is included in Spring Session.
<3> We create a `transactionManager` that manages transactions for previously configured `dataSource`.
For additional information on how to configure data access related concerns, please refer to the http://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-data-tier.html[Spring Framework Reference Documentation].
For additional information on how to configure data access related concerns, please refer to the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/data-access.html[Spring Framework Reference Documentation].
== XML Servlet Container Initialization
@@ -105,7 +105,7 @@ include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/web.xml[tags=context-para
include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/web.xml[tags=listeners]
----
The http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-create[ContextLoaderListener] reads the contextConfigLocation and picks up our session.xml configuration.
The https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/core.html#context-create[ContextLoaderListener] reads the contextConfigLocation and picks up our session.xml configuration.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
The following snippet performs this last step for us:
@@ -116,7 +116,7 @@ The following snippet performs this last step for us:
include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/web.xml[tags=springSessionRepositoryFilter]
----
The http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] will look up a Bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`.
The https://docs.spring.io/spring-framework/docs/{spring-framework-version}/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] will look up a Bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`.
For every request that `DelegatingFilterProxy` is invoked, the `springSessionRepositoryFilter` will be invoked.
// end::config[]
@@ -155,7 +155,7 @@ include::{samples-dir}xml/jdbc/src/main/java/sample/SessionServlet.java[tags=cla
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in H2 database.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL)

View File

@@ -31,7 +31,7 @@ If you are using Maven, ensure to add the following dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-version}</version>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
@@ -90,7 +90,7 @@ The filter is what is in charge of replacing the `HttpSession` implementation to
In this instance Spring Session is backed by Redis.
<2> We create a `RedisConnectionFactory` that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379)
For more information on configuring Spring Data Redis, refer to the http://docs.spring.io/spring-data/data-redis/docs/current/reference/html/[reference documentation].
For more information on configuring Spring Data Redis, refer to the https://docs.spring.io/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation].
== XML Servlet Container Initialization
@@ -108,7 +108,7 @@ include::{samples-dir}xml/redis/src/main/webapp/WEB-INF/web.xml[tags=context-par
include::{samples-dir}xml/redis/src/main/webapp/WEB-INF/web.xml[tags=listeners]
----
The http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-create[ContextLoaderListener] reads the contextConfigLocation and picks up our session.xml configuration.
The https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/core.html#context-create[ContextLoaderListener] reads the contextConfigLocation and picks up our session.xml configuration.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
The following snippet performs this last step for us:
@@ -119,7 +119,7 @@ The following snippet performs this last step for us:
include::{samples-dir}xml/redis/src/main/webapp/WEB-INF/web.xml[tags=springSessionRepositoryFilter]
----
The http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] will look up a Bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`.
The https://docs.spring.io/spring-framework/docs/{spring-framework-version}/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] will look up a Bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`.
For every request that `DelegatingFilterProxy` is invoked, the `springSessionRepositoryFilter` will be invoked.
// end::config[]
@@ -133,7 +133,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking
[NOTE]
====
For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
@@ -165,13 +165,13 @@ include::{samples-dir}xml/redis/src/main/java/sample/SessionServlet.java[tags=cl
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in Redis.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for http://redis.io/topics/quickstart[installing redis-cli].
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:

View File

@@ -1,6 +1,5 @@
= Spring Session
Rob Winch, Vedran Pavić, Jakub Kubrynski
Rob Winch, Vedran Pavić
:doctype: book
:indexdoc-tests: {docs-test-dir}docs/IndexDocTests.java
:websocketdoc-test-dir: {docs-test-dir}docs/websocket/
@@ -13,29 +12,31 @@ Spring Session provides an API and implementations for managing a user's session
[[introduction]]
== Introduction
Spring Session provides an API and implementations for managing a user's session information. It also provides transparent integration with:
* <<httpsession,HttpSession>> - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way.
Additional features include:
** **Clustered Sessions** - Spring Session makes it trivial to support <<httpsession-redis,clustered sessions>> without being tied to an application container specific solution.
** **RESTful APIs** - Spring Session allows providing session ids in headers to work with <<httpsession-rest,RESTful APIs>>
Spring Session provides an API and implementations for managing a user's session information, while also making it trivial to support clustered sessions without being tied to an application container specific solution.
It also provides transparent integration with:
* <<httpsession,HttpSession>> - allows replacing the `HttpSession` in an application container (i.e. Tomcat) neutral way, with support for providing session IDs in headers to work with RESTful APIs.
* <<websocket,WebSocket>> - provides the ability to keep the `HttpSession` alive when receiving WebSocket messages
* <<websession,WebSession>> - allows replacing the Spring WebFlux's `WebSession` in an application container neutral way.
== What's New in 1.3
== What's New in 2.0
Below are the highlights of what is new in Spring Session 1.3. You can find a complete list of what's new by referring to the changelogs of
https://github.com/spring-projects/spring-session/milestone/6?closed=1[1.3.0.M1],
https://github.com/spring-projects/spring-session/milestone/18?closed=1[1.3.0.M2],
https://github.com/spring-projects/spring-session/milestone/16?closed=1[1.3.0.RC1], and
https://github.com/spring-projects/spring-session/milestone/19?closed=1[1.3.0.RELEASE].
Below are the highlights of what is new in Spring Session 2.0. You can find a complete list of what's new by referring to the changelogs of
https://github.com/spring-projects/spring-session/milestone/17?closed=1[2.0.0.M1],
https://github.com/spring-projects/spring-session/milestone/22?closed=1[2.0.0.M2],
https://github.com/spring-projects/spring-session/milestone/23?closed=1[2.0.0.M3],
https://github.com/spring-projects/spring-session/milestone/24?closed=1[2.0.0.M4],
https://github.com/spring-projects/spring-session/milestone/25?closed=1[2.0.0.M5],
https://github.com/spring-projects/spring-session/milestone/26?closed=1[2.0.0.RC1],
https://github.com/spring-projects/spring-session/milestone/27?closed=1[2.0.0.RC2], and
https://github.com/spring-projects/spring-session/milestone/30?closed=1[2.0.0.RELEASE].
* First class support for http://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/#httpsession-hazelcast[Hazelcast]
* First class support for http://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/#spring-security-concurrent-sessions-how[Spring Security's concurrent session management]
* Added https://github.com/maseev/spring-session-orientdb[OrientDB Community Extension]
* https://github.com/spring-projects/spring-session/tree/1.3.0.RELEASE/samples/httpsession-redis-json[GenericJackson2JsonRedisSerializer sample] with Spring Security's new Jackson Support
* Guides now https://github.com/spring-projects/spring-session/pull/652[use Lettuce]
* `spring.session.cleanup.cron.expression` can be used to override the cleanup tasks cron expression
* Upgraded to Java 8 and Spring Framework 5 as baseline
* https://github.com/spring-projects/spring-session/issues/683[Added support for managing Spring WebFlux's `WebSession`] with https://github.com/spring-projects/spring-session/issues/816[Redis `ReactiveSessionRepository`]
* https://github.com/spring-projects/spring-session/issues/768[Extracted `SessionRepository` implementations to separate modules]
* Improved https://github.com/spring-projects/spring-session/issues/682[`Session`] and https://github.com/spring-projects/spring-session/issues/809[`SessionRepository`] APIs
* Improved and harmonized configuration support for all supported session stores
* https://github.com/spring-projects/spring-session/pull/713[Added support for configuring default `CookieSerializer` using `SessionCookieConfig`]
* Lots of performance improvements and bug fixes
[[samples]]
@@ -63,6 +64,10 @@ If you are looking to get started with Spring Session, the best place to start i
| Demonstrates how to use Spring Session with WebSockets.
| link:guides/boot-websocket.html[WebSockets Guide]
| {gh-samples-url}boot/webflux[WebFlux]
| Demonstrates how to use Spring Session to replace the Spring WebFlux's `WebSession` with Redis.
| TBD
| {gh-samples-url}boot/redis-json[HttpSession with Redis JSON serialization]
| Demonstrates how to use Spring Session to replace the `HttpSession` with Redis using JSON serialization.
| TBD
@@ -127,6 +132,27 @@ If you are looking to get started with Spring Session, the best place to start i
|===
[[modules]]
== Spring Session Modules
In Spring Session 1.x all of the Spring Session's `SessionRepository` implementations were available within the `spring-session` artifact.
While convenient, this approach wasn't sustainable long-term as more features and `SessionRepository` implementations were added to the project.
Starting with Spring Session 2.0, the project has been split up to Spring Session Core module, and several other modules that carry `SessionRepository` implementations and functionality related to the specific data store.
The users of Spring Data will find this arrangement familiar, with Spring Session Core module taking a role equivalent to Spring Data Commons and providing core functionalities and APIs with other modules containing data store specific implementations.
As a part of this split, the Spring Session Data MongoDB and Spring Session Data GemFire modules were moved to separate repositories so the situation with project's repositories/modules is a follows:
* https://github.com/spring-projects/spring-session[`spring-session` repository]
** Hosts Spring Session Core, Spring Session Data Redis, Spring Session JDBC and Spring Session Hazelcast modules
* https://github.com/spring-projects/spring-session-data-mongodb[`spring-session-data-mongodb` repository]
** Hosts Spring Session Data MongoDB module
* https://github.com/spring-projects/spring-session-data-geode[`spring-session-data-geode` repository]
** Hosts Spring Session Data Geode/GemFire module
Going forward, the plan is to externalize each of the `SessionRepository` implementations into a dedicated repository and provide a Maven BOM (as in "bill of materials") module in order to help users with version management concerns.
Modules maintained by the members of Spring Team will be hosted within the https://github.com/spring-projects[`spring-projects` organization], while the community maintained modules will continue to be promoted via <<community-extensions,Community Extensions>> section of this manual.
[[httpsession]]
== HttpSession Integration
@@ -139,7 +165,7 @@ This means that developers can switch the `HttpSession` implementation out with
We have already mentioned that Spring Session provides transparent integration with `HttpSession`, but what benefits do we get out of this?
* **Clustered Sessions** - Spring Session makes it trivial to support <<httpsession-redis,clustered sessions>> without being tied to an application container specific solution.
* **RESTful APIs** - Spring Session allows providing session ids in headers to work with <<httpsession-rest,RESTful APIs>>
* **RESTful APIs** - Spring Session allows providing session IDs in headers to work with <<httpsession-rest,RESTful APIs>>
[[httpsession-redis]]
=== HttpSession with Redis
@@ -348,6 +374,116 @@ Before using WebSocket integration, you should be sure that you have <<httpsessi
include::guides/boot-websocket.adoc[tags=config,leveloffset=+2]
[[websession]]
== WebSession Integration
Spring Session provides transparent integration with Spring WebFlux's `WebSession`.
This means that developers can switch the `WebSession` implementation out with an implementation that is backed by Spring Session.
[[websession-why]]
=== Why Spring Session & WebSession?
We have already mentioned that Spring Session provides transparent integration with Spring WebFlux's `WebSession`, but what benefits do we get out of this?
As with `HttpSession`, Spring Session makes it trivial to support <<websession-redis,clustered sessions>> without being tied to an application container specific solution.
[[websession-redis]]
=== WebSession with Redis
Using Spring Session with `WebSession` is enabled by simply registering a `WebSessionManager` implementation backed by Spring Session's `ReactiveSessionRepository`.
The Spring configuration is responsible for creating a `WebSessionManager` that replaces the `WebSession` implementation with an implementation backed by Spring Session.
Add the following Spring Configuration:
[source, java]
----
@EnableRedisWebSession // <1>
public class SessionConfiguration {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(); // <2>
}
}
----
<1> The `@EnableRedisWebSession` annotation creates a Spring Bean with the name of `webSessionManager` that implements the `WebSessionManager`.
This is what is in charge of replacing the `WebSession` implementation to be backed by Spring Session.
In this instance Spring Session is backed by Redis.
<2> We create a `RedisConnectionFactory` that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379)
For more information on configuring Spring Data Redis, refer to the https://docs.spring.io/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation].
[[websession-how]]
=== How WebSession Integration Works
With Spring WebFlux and it's `WebSession` things are considerably simpler for Spring Session to integrate with, compared to Servlet API and it's `HttpSession`.
Spring WebFlux provides `WebSessionStore` API which presents a strategy for persisting `WebSession`.
NOTE: This section describes how Spring Session provides transparent integration with `WebSession`. The intent is so that user's can understand what is happening under the covers. This functionality is already integrated and you do NOT need to implement this logic yourself.
First we create a custom `SpringSessionWebSession` that delegates to Spring Session's `Session`.
It looks something like the following:
[source, java]
----
public class SpringSessionWebSession implements WebSession {
enum State {
NEW, STARTED
}
private final S session;
private AtomicReference<State> state = new AtomicReference<>();
SpringSessionWebSession(S session, State state) {
this.session = session;
this.state.set(state);
}
@Override
public void start() {
this.state.compareAndSet(State.NEW, State.STARTED);
}
@Override
public boolean isStarted() {
State value = this.state.get();
return (State.STARTED.equals(value)
|| (State.NEW.equals(value) && !this.session.getAttributes().isEmpty()));
}
@Override
public Mono<Void> changeSessionId() {
return Mono.defer(() -> {
this.session.changeSessionId();
return save();
});
}
// ... other methods delegate to the original Session
}
----
Next, we create a custom `WebSessionStore` that delegates to the `ReactiveSessionRepository` and wraps `Session` into custom `WebSession` implementation:
[source, java]
----
public class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore {
private final ReactiveSessionRepository<S> sessions;
public SpringSessionWebSessionStore(ReactiveSessionRepository<S> reactiveSessionRepository) {
this.sessions = reactiveSessionRepository;
}
// ...
}
----
In order to be detected by Spring WebFlux, this custom `WebSessionStore` needs to be registered with `ApplicationContext` as bean named `webSessionManager`.
For additional information on Spring WebFlux, refer to the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/web-reactive.html[Spring Framework Reference Documentation].
[[spring-security]]
== Spring Security Integration
@@ -356,7 +492,7 @@ Spring Session provides integration with Spring Security.
[[spring-security-rememberme]]
=== Spring Security Remember-Me Support
Spring Session provides integration with http://docs.spring.io/spring-security/site/docs/4.2.x/reference/htmlsingle/#remember-me[Spring Security's Remember-Me Authentication].
Spring Session provides integration with https://docs.spring.io/spring-security/site/docs/{spring-security-version}/reference/htmlsingle/#remember-me[Spring Security's Remember-Me Authentication].
The support will:
* Change the session expiration length
@@ -502,6 +638,14 @@ Once the session is indexed, it can be found using the following:
include::{docs-test-dir}docs/FindByIndexNameSessionRepositoryTests.java[tags=findby-username]
----
[[api-reactivesessionrepository]]
=== ReactiveSessionRepository
A `ReactiveSessionRepository` is in charge of creating, retrieving, and persisting `Session` instances in a non-blocking and reactive manner.
If possible, developers should not interact directly with a `ReactiveSessionRepository` or a `Session`.
Instead, developers should prefer interacting with `ReactiveSessionRepository` and `Session` indirectly through the <<websession,WebSession>> integration.
[[api-enablespringhttpsession]]
=== EnableSpringHttpSession
@@ -518,6 +662,22 @@ It is important to note that no infrastructure for session expirations is config
This is because things like session expiration are highly implementation dependent.
This means if you require cleaning up expired sessions, you are responsible for cleaning up the expired sessions.
[[api-enablespringwebsession]]
=== EnableSpringWebSession
The `@EnableSpringWebSession` annotation can be added to an `@Configuration` class to expose the `WebSessionManager` as a bean named "webSessionManager".
In order to leverage the annotation, a single `ReactiveSessionRepository` bean must be provided.
For example:
[source,java,indent=0]
----
include::{docs-test-dir}docs/SpringWebSessionConfig.java[tags=class]
----
It is important to note that no infrastructure for session expirations is configured for you out of the box.
This is because things like session expiration are highly implementation dependent.
This means if you require cleaning up expired sessions, you are responsible for cleaning up the expired sessions.
[[api-redisoperationssessionrepository]]
=== RedisOperationsSessionRepository
@@ -545,7 +705,7 @@ Complete example usage can be found in the <<samples>>
You can use the following attributes to customize the configuration:
* **maxInactiveIntervalInSeconds** - the amount of time before the session will expire in seconds
* **redisNamespace** - allows configuring an application specific namespace for the sessions. Redis keys and channel ids will start with the prefix of `<redisNamespace>:`.
* **redisNamespace** - allows configuring an application specific namespace for the sessions. Redis keys and channel IDs will start with the prefix of `<redisNamespace>:`.
* **redisFlushMode** - allows specifying when data will be written to Redis. The default is only when `save` is invoked on `SessionRepository`.
A value of `RedisFlushMode.IMMEDIATE` will write to Redis as soon as possible.
@@ -557,7 +717,7 @@ You can customize the serialization by creating a Bean named `springSessionDefau
`RedisOperationsSessionRepository` is subscribed to receive events from redis using a `RedisMessageListenerContainer`.
You can customize the way those events are dispatched, by creating a Bean named `springSessionRedisTaskExecutor` and/or a Bean `springSessionRedisSubscriptionExecutor`.
More details on configuring redis task executors can be found http://docs.spring.io/spring-data-redis/docs/current/reference/html/#redis:pubsub:subscribe:containers[here].
More details on configuring redis task executors can be found https://docs.spring.io/spring-data-redis/docs/{spring-data-redis-version}/reference/html/#redis:pubsub:subscribe:containers[here].
[[api-redisoperationssessionrepository-storage]]
==== Storage Details
@@ -596,7 +756,7 @@ HMSET spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe creationTime
In this example, the session following statements are true about the session:
* The session id is 33fdd1b6-b496-4b33-9f7d-df96679d32fe
* The session ID is 33fdd1b6-b496-4b33-9f7d-df96679d32fe
* The session was created at 1404360000000 in milliseconds since midnight of 1/1/1970 GMT.
* The session expires in 1800 seconds (30 minutes).
* The session was last accessed at 1404360000000 in milliseconds since midnight of 1/1/1970 GMT.
@@ -636,7 +796,7 @@ The `SessionRepository.findById(String)` method ensures that no expired sessions
This means there is no need to check the expiration before using a session.
====
Spring Session relies on the delete and expired http://redis.io/topics/notifications[keyspace notifications] from Redis to fire a <<api-redisoperationssessionrepository-sessiondestroyedevent,SessionDeletedEvent>> and <<api-redisoperationssessionrepository-sessiondestroyedevent,SessionExpiredEvent>> respectively.
Spring Session relies on the delete and expired https://redis.io/topics/notifications[keyspace notifications] from Redis to fire a <<api-redisoperationssessionrepository-sessiondestroyedevent,SessionDeletedEvent>> and <<api-redisoperationssessionrepository-sessiondestroyedevent,SessionExpiredEvent>> respectively.
It is the `SessionDeletedEvent` or `SessionExpiredEvent` that ensures resources associated with the Session are cleaned up.
For example, when using Spring Session's WebSocket support the Redis expired or delete event is what triggers any WebSocket connections associated with the session to be closed.
@@ -651,7 +811,7 @@ When a session expires key is deleted or expires, the keyspace notification trig
One problem with relying on Redis expiration exclusively is that Redis makes no guarantee of when the expired event will be fired if the key has not been accessed.
Specifically the background task that Redis uses to clean up expired keys is a low priority task and may not trigger the key expiration.
For additional details see http://redis.io/topics/notifications[Timing of expired events] section in the Redis documentation.
For additional details see https://redis.io/topics/notifications[Timing of expired events] section in the Redis documentation.
To circumvent the fact that expired events are not guaranteed to happen we can ensure that each key is accessed when it is expected to expire.
This means that if the TTL is expired on the key, Redis will remove the key and fire the expired event when we try to access the key.
@@ -686,7 +846,7 @@ This is necessary to ensure resources associated with the `Session` are properly
For example, when integrating with WebSockets the `SessionDestroyedEvent` is in charge of closing any active WebSocket connections.
Firing `SessionDeletedEvent` or `SessionExpiredEvent` is made available through the `SessionMessageListener` which listens to http://redis.io/topics/notifications[Redis Keyspace events].
Firing `SessionDeletedEvent` or `SessionExpiredEvent` is made available through the `SessionMessageListener` which listens to https://redis.io/topics/notifications[Redis Keyspace events].
In order for this to work, Redis Keyspace events for Generic commands and Expired events needs to be enabled.
For example:
@@ -718,14 +878,14 @@ include::{docs-test-resources-dir}docs/HttpSessionConfigurationNoOpConfigureRedi
==== SessionCreatedEvent
When a session is created an event is sent to Redis with the channel of `spring:session:channel:created:33fdd1b6-b496-4b33-9f7d-df96679d32fe`
such that `33fdd1b6-b496-4b33-9f7d-df96679d32fe` is the session id. The body of the event will be the session that was created.
such that `33fdd1b6-b496-4b33-9f7d-df96679d32fe` is the session ID. The body of the event will be the session that was created.
If registered as a MessageListener (default), then `RedisOperationsSessionRepository` will then translate the Redis message into a `SessionCreatedEvent`.
[[api-redisoperationssessionrepository-cli]]
==== Viewing the Session in Redis
After http://redis.io/topics/quickstart[installing redis-cli], you can inspect the values in Redis http://redis.io/commands#hash[using the redis-cli].
After https://redis.io/topics/quickstart[installing redis-cli], you can inspect the values in Redis https://redis.io/commands#hash[using the redis-cli].
For example, enter the following into a terminal:
[source,bash]
@@ -737,7 +897,70 @@ redis 127.0.0.1:6379> keys *
----
<1> The suffix of this key is the session identifier of the Spring Session.
<2> This key contains all the session ids that should be deleted at the time `1418772300000`.
<2> This key contains all the session IDs that should be deleted at the time `1418772300000`.
You can also view the attributes of each session.
[source,bash]
----
redis 127.0.0.1:6379> hkeys spring:session:sessions:4fc39ce3-63b3-4e17-b1c4-5e1ed96fb021
1) "lastAccessedTime"
2) "creationTime"
3) "maxInactiveInterval"
4) "sessionAttr:username"
redis 127.0.0.1:6379> hget spring:session:sessions:4fc39ce3-63b3-4e17-b1c4-5e1ed96fb021 sessionAttr:username
"\xac\xed\x00\x05t\x00\x03rob"
----
[[api-reactiveredisoperationssessionrepository]]
=== ReactiveRedisOperationsSessionRepository
`ReactiveRedisOperationsSessionRepository` is a `ReactiveSessionRepository` that is implemented using Spring Data's `ReactiveRedisOperations`.
In a web environment, this is typically used in combination with `WebSessionStore`.
[[api-reactiveredisoperationssessionrepository-new]]
==== Instantiating a ReactiveRedisOperationsSessionRepository
A typical example of how to create a new instance can be seen below:
[source,java,indent=0]
----
include::{indexdoc-tests}[tags=new-reactiveredisoperationssessionrepository]
----
For additional information on how to create a `ReactiveRedisConnectionFactory`, refer to the Spring Data Redis Reference.
[[api-reactiveredisoperationssessionrepository-config]]
==== EnableRedisWebSession
In a web environment, the simplest way to create a new `ReactiveRedisOperationsSessionRepository` is to use `@EnableRedisWebSession`.
You can use the following attributes to customize the configuration:
* **maxInactiveIntervalInSeconds** - the amount of time before the session will expire in seconds
* **redisNamespace** - allows configuring an application specific namespace for the sessions. Redis keys and channel IDs will start with the prefix of `<redisNamespace>:`.
* **redisFlushMode** - allows specifying when data will be written to Redis. The default is only when `save` is invoked on `ReactiveSessionRepository`.
A value of `RedisFlushMode.IMMEDIATE` will write to Redis as soon as possible.
[[api-reactiveredisoperationssessionrepository-writes]]
===== Optimized Writes
The `Session` instances managed by `ReactiveRedisOperationsSessionRepository` keeps track of the properties that have changed and only updates those.
This means if an attribute is written once and read many times we only need to write that attribute once.
[[api-reactiveredisoperationssessionrepository-cli]]
==== Viewing the Session in Redis
After https://redis.io/topics/quickstart[installing redis-cli], you can inspect the values in Redis https://redis.io/commands#hash[using the redis-cli].
For example, enter the following into a terminal:
[source,bash]
----
$ redis-cli
redis 127.0.0.1:6379> keys *
1) "spring:session:sessions:4fc39ce3-63b3-4e17-b1c4-5e1ed96fb021" <1>
----
<1> The suffix of this key is the session identifier of the Spring Session.
You can also view the attributes of each session.
@@ -755,7 +978,7 @@ redis 127.0.0.1:6379> hget spring:session:sessions:4fc39ce3-63b3-4e17-b1c4-5e1ed
[[api-mapsessionrepository]]
=== MapSessionRepository
The `MapSessionRepository` allows for persisting `Session` in a `Map` with the key being the `Session` id and the value being the `Session`.
The `MapSessionRepository` allows for persisting `Session` in a `Map` with the key being the `Session` ID and the value being the `Session`.
The implementation can be used with a `ConcurrentHashMap` as a testing or convenience mechanism.
Alternatively, it can be used with distributed `Map` implementations. For example, it can be used with Hazelcast.
@@ -786,6 +1009,13 @@ To run it use the following:
./gradlew :samples:hazelcast-spring:tomcatRun
[[api-reactivemapsessionrepository]]
=== ReactiveMapSessionRepository
The `ReactiveMapSessionRepository` allows for persisting `Session` in a `Map` with the key being the `Session` ID and the value being the `Session`.
The implementation can be used with a `ConcurrentHashMap` as a testing or convenience mechanism.
Alternatively, it can be used with distributed `Map` implementations with the requirement that the supplied `Map` must be a non-blocking.
[[api-jdbcoperationssessionrepository]]
=== JdbcOperationsSessionRepository
@@ -803,7 +1033,7 @@ A typical example of how to create a new instance can be seen below:
include::{indexdoc-tests}[tags=new-jdbcoperationssessionrepository]
----
For additional information on how to create and configure `JdbcTemplate` and `PlatformTransactionManager`, refer to the http://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-data-tier.html[Spring Framework Reference Documentation].
For additional information on how to create and configure `JdbcTemplate` and `PlatformTransactionManager`, refer to the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/data-access.html[Spring Framework Reference Documentation].
[[api-jdbcoperationssessionrepository-config]]
==== EnableJdbcHttpSession
@@ -870,12 +1100,12 @@ A typical example of how to create a new instance can be seen below:
include::{indexdoc-tests}[tags=new-hazelcastsessionrepository]
----
For additional information on how to create and configure Hazelcast instance, refer to the http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#hazelcast-configuration[Hazelcast documentation].
For additional information on how to create and configure Hazelcast instance, refer to the http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[Hazelcast documentation].
[[api-enablehazelcasthttpsession]]
==== EnableHazelcastHttpSession
If you wish to use http://hazelcast.org/[Hazelcast] as your backing source for the `SessionRepository`, then the `@EnableHazelcastHttpSession` annotation
If you wish to use https://hazelcast.org/[Hazelcast] as your backing source for the `SessionRepository`, then the `@EnableHazelcastHttpSession` annotation
can be added to an `@Configuration` class. This extends the functionality provided by the `@EnableSpringHttpSession` annotation but makes the `SessionRepository` for you in Hazelcast.
You must provide a single `HazelcastInstance` bean for the configuration to work.
Complete configuration example can be found in the <<samples>>
@@ -907,6 +1137,70 @@ Note that if you use Hazelcast's `MapStore` to persist your sessions `IMap` ther
* reload triggers `EntryAddedListener` which results in `SessionCreatedEvent` being re-published
* reload uses default TTL for a given `IMap` which results in sessions losing their original TTL
[[custom-sessionrepository]]
== Custom SessionRepository
Implementing a custom <<api-sessionrepository,`SessionRepository`>> API should be a fairly straightforward task.
Coupling the custom implementation with <<api-enablespringhttpsession,`@EnableSpringHttpSession`>> support allow to easily reuse existing Spring Session configuration facilities and infrastructure.
There are however a couple of aspects that deserve a closer consideration.
During a lifecycle of an HTTP request, the `HttpSession` is typically is persisted to `SessionRepository` twice.
First to ensure that the session is available to the clients as soon as the client has access to the session ID, and it is also necessary to write after the session is committed because further modifications to the session might be made.
Having this in mind, it is generally recommended for a `SessionRepository` implementation to keep track of changes to ensure that only deltas are saved.
This is in particular very important in highly concurrent environments, where multiple requests operate on the same `HttpSession` and therefore cause race conditions, with requests overriding each others changes to session attributes.
All of the `SessionRepository` implementations provided by Spring Session use the described approach to persisting session changes and can be used for guidance while implementing custom `SessionRepository`.
Note that the same recommendations apply for implementing a custom <<api-reactivesessionrepository,`ReactiveSessionRepository`>> as well.
Of course, in this case the <<api-enablespringwebsession,`@EnableSpringWebSession`>> should be used.
[[upgrading-2.0]]
== Upgrading to 2.x
With the new major release version, the Spring Session team took the opportunity to make some non-passive changes.
The focus of these changes is to improve and harmonize Spring Session's APIs, as well as remove the deprecated components.
=== Baseline update
Spring Session 2.0 requires Java 8 and Spring Framework 5.0 as a baseline, since its entire codebase is now based on Java 8 source code.
Refer to guide for https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x[Upgrading to Spring Framework 5.x] for reference on upgrading Spring Framework.
=== Replaced and Removed Modules
As a part of the project's split the modules, the existing `spring-session` has been replaced with `spring-session-core` module.
The `spring-session-core` module holds only the common set of APIs and components while other modules contain the implementation of appropriate `SessionRepository` and functionality related to that data store.
This applies to several existing that were previously a simple dependency aggregator helper modules but with new module arrangement actually carry the implementation:
* Spring Session Data Redis
* Spring Session JDBC
* Spring Session Hazelcast
Also the following modules were removed from the main project repository:
* Spring Session Data MongoDB
* Spring Session Data GemFire
Note that these two have moved to separate repositories, and will continue to be available albeit under a changed artifact names:
* https://github.com/spring-projects/spring-session-data-mongodb[`spring-session-data-mongodb`]
* https://github.com/spring-projects/spring-session-data-geode[`spring-session-data-geode`]
=== Replaced and Removed Packages, Classes and Methods
* `ExpiringSession` API has been merged into `Session` API
* `Session` API has been enhanced to make full use of Java 8
* `Session` API has been extended with `changeSessionId` support
* `SessionRepository` API has been updated to better align with Spring Data method naming conventions
* `AbstractSessionEvent` and its subclasses are no longer constructable without an underlying `Session` object
* Redis namespace used by `RedisOperationsSessionRepository` is now fully configurable, instead of being partial configurable
* Redis configuration support has been updated to avoid registering a Spring Session specific `RedisTemplate` bean
* JDBC configuration support has been updated to avoid registering a Spring Session specific `JdbcTemplate` bean
* Previously deprecated classes and methods have been removed across the codebase
=== Dropped Support
As a part of the changes to `HttpSessionStrategy` and it's alignment to the counterpart from the reactive world, the support for managing multiple users' sessions in a single browser instance has been removed.
This introduction of new API to replace this functionality in consideration for future releases.
[[community]]
== Spring Session Community
@@ -916,18 +1210,18 @@ Please find additional information below.
[[community-support]]
=== Support
You can get help by asking questions on http://stackoverflow.com/questions/tagged/spring-session[StackOverflow with the tag spring-session].
You can get help by asking questions on https://stackoverflow.com/questions/tagged/spring-session[StackOverflow with the tag spring-session].
Similarly we encourage helping others by answering questions on StackOverflow.
[[community-source]]
=== Source Code
Our source code can be found on github at https://github.com/spring-projects/spring-session/
Our source code can be found on GitHub at https://github.com/spring-projects/spring-session/
[[community-issues]]
=== Issue Tracking
We track issues in github issues at https://github.com/spring-projects/spring-session/issues
We track issues in GitHub issues at https://github.com/spring-projects/spring-session/issues
[[community-contributing]]
=== Contributing
@@ -937,7 +1231,7 @@ We appreciate https://help.github.com/articles/using-pull-requests/[Pull Request
[[community-license]]
=== License
Spring Session is Open Source software released under the http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].
Spring Session is Open Source software released under the https://www.apache.org/licenses/LICENSE-2.0[Apache 2.0 license].
[[community-extensions]]
=== Community Extensions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,14 +24,20 @@ import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.junit.Test;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.mock.web.MockServletContext;
import org.springframework.session.MapSession;
import org.springframework.session.MapSessionRepository;
import org.springframework.session.ReactiveSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.hazelcast.HazelcastSessionRepository;
import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
@@ -120,6 +126,26 @@ public class IndexDocTests {
// end::new-redisoperationssessionrepository[]
}
@Test
@SuppressWarnings("unused")
public void newReactiveRedisOperationsSessionRepository() {
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
RedisSerializationContext<String, Object> serializationContext = RedisSerializationContext
.<String, Object>newSerializationContext(
new JdkSerializationRedisSerializer())
.build();
// tag::new-reactiveredisoperationssessionrepository[]
// ... create and configure connectionFactory and serializationContext ...
ReactiveRedisTemplate<String, Object> redisTemplate = new ReactiveRedisTemplate<>(
connectionFactory, serializationContext);
ReactiveSessionRepository<? extends Session> repository =
new ReactiveRedisOperationsSessionRepository(redisTemplate);
// end::new-reactiveredisoperationssessionrepository[]
}
@Test
@SuppressWarnings("unused")
public void mapRepository() {

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2014-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docs;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.context.annotation.Bean;
import org.springframework.session.ReactiveMapSessionRepository;
import org.springframework.session.ReactiveSessionRepository;
import org.springframework.session.config.annotation.web.server.EnableSpringWebSession;
// tag::class[]
@EnableSpringWebSession
public class SpringWebSessionConfig {
@Bean
public ReactiveSessionRepository reactiveSessionRepository() {
return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
}
}
// end::class[]