209 lines
7.0 KiB
Plaintext
209 lines
7.0 KiB
Plaintext
= Spring Session - HttpSession (Quick Start)
|
|
Rob Winch, Vedran Pavić
|
|
:toc: left
|
|
:stylesdir: ../
|
|
:highlightjsdir: ../js/highlight
|
|
:docinfodir: guides
|
|
|
|
This guide describes how to use Spring Session to transparently leverage a relational database to back a web application's `HttpSession` with Java Configuration.
|
|
|
|
NOTE: You can find the completed guide in the <<httpsession-jdbc-sample, httpsession-jdbc sample application>>.
|
|
|
|
[#index-link]
|
|
link:../index.html[Index]
|
|
|
|
== Updating Dependencies
|
|
|
|
Before you use Spring Session, you must update your dependencies.
|
|
If you use Maven, you must add the following dependencies:
|
|
|
|
====
|
|
.pom.xml
|
|
[source,xml]
|
|
[subs="verbatim,attributes"]
|
|
----
|
|
<dependencies>
|
|
<!-- ... -->
|
|
|
|
<dependency>
|
|
<groupId>org.springframework.session</groupId>
|
|
<artifactId>spring-session-jdbc</artifactId>
|
|
<version>{spring-session-version}</version>
|
|
<type>pom</type>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework</groupId>
|
|
<artifactId>spring-web</artifactId>
|
|
<version>{spring-framework-version}</version>
|
|
</dependency>
|
|
</dependencies>
|
|
----
|
|
====
|
|
|
|
ifeval::["{version-snapshot}" == "true"]
|
|
Since we are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
|
|
You must have the following in your pom.xml:
|
|
|
|
====
|
|
.pom.xml
|
|
[source,xml]
|
|
----
|
|
<repositories>
|
|
|
|
<!-- ... -->
|
|
|
|
<repository>
|
|
<id>spring-snapshot</id>
|
|
<url>https://repo.spring.io/libs-snapshot</url>
|
|
</repository>
|
|
</repositories>
|
|
----
|
|
====
|
|
endif::[]
|
|
|
|
ifeval::["{version-milestone}" == "true"]
|
|
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
|
|
You must have the following in your pom.xml:
|
|
|
|
====
|
|
.pom.xml
|
|
[source,xml]
|
|
----
|
|
<repository>
|
|
<id>spring-milestone</id>
|
|
<url>https://repo.spring.io/libs-milestone</url>
|
|
</repository>
|
|
----
|
|
====
|
|
endif::[]
|
|
|
|
// tag::config[]
|
|
|
|
[[httpsession-jdbc-spring-configuration]]
|
|
== Spring Java Configuration
|
|
|
|
After adding the required dependencies, we can create our Spring configuration.
|
|
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.
|
|
To do so, add the following Spring Configuration:
|
|
|
|
====
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}spring-session-sample-javaconfig-jdbc/src/main/java/sample/Config.java[tags=class]
|
|
----
|
|
|
|
<1> The `@EnableJdbcHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter`.
|
|
That bean implements `Filter`.
|
|
The filter is in charge of replacing the `HttpSession` implementation to be backed by Spring Session.
|
|
In this instance, Spring Session is backed by a relational database.
|
|
<2> We create a `dataSource` that connects Spring Session to an embedded instance of an H2 database.
|
|
We configure the H2 database to create database tables by using the SQL script that 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, see the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/data-access.html[Spring Framework Reference Documentation].
|
|
|
|
== Java Servlet Container Initialization
|
|
|
|
Our <<httpsession-jdbc-spring-configuration,Spring Configuration>> created a Spring bean named `springSessionRepositoryFilter` that implements `Filter`.
|
|
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
|
|
|
|
In order for our `Filter` to do its magic, Spring needs to load our `Config` class.
|
|
Last, we need to ensure that our Servlet Container (that is, Tomcat) uses our `springSessionRepositoryFilter` for every request.
|
|
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both of these steps easy.
|
|
The following example shows how to do so:
|
|
|
|
====
|
|
.src/main/java/sample/Initializer.java
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}spring-session-sample-javaconfig-jdbc/src/main/java/sample/Initializer.java[tags=class]
|
|
----
|
|
|
|
NOTE: The name of our class (Initializer) does not matter.
|
|
What is important is that we extend `AbstractHttpSessionApplicationInitializer`.
|
|
|
|
<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`.
|
|
Doing so ensures that the Spring bean named `springSessionRepositoryFilter` is registered with our Servlet Container for every request.
|
|
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to ensure Spring loads our `Config`.
|
|
====
|
|
|
|
== Multiple DataSources
|
|
Spring Session provides the `@SpringSessionDataSource` qualifier, allowing you to explicitly declare which `DataSource` bean should be injected in `JdbcIndexedSessionRepository`.
|
|
This is particularly useful in scenarios with multiple `DataSource` beans present in the application context.
|
|
|
|
The following example shows how to do so:
|
|
|
|
====
|
|
.Config.java
|
|
[source,java]
|
|
----
|
|
@EnableJdbcHttpSession
|
|
public class Config {
|
|
|
|
@Bean
|
|
@SpringSessionDataSource // <1>
|
|
public EmbeddedDatabase firstDataSource() {
|
|
return new EmbeddedDatabaseBuilder()
|
|
.setType(EmbeddedDatabaseType.H2).addScript("org/springframework/session/jdbc/schema-h2.sql").build();
|
|
}
|
|
|
|
@Bean
|
|
public HikariDataSource secondDataSource() {
|
|
// ...
|
|
}
|
|
}
|
|
----
|
|
|
|
<1> This qualifier declares that firstDataSource is to be used by Spring Session.
|
|
====
|
|
|
|
// end::config[]
|
|
|
|
[[httpsession-jdbc-sample]]
|
|
== `httpsession-jdbc` Sample Application
|
|
|
|
This section describes how to work with the `httpsession-jdbc` Sample Application.
|
|
|
|
=== Running the `httpsession-jdbc` Sample Application
|
|
|
|
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
|
|
|
|
====
|
|
----
|
|
$ ./gradlew :spring-session-sample-javaconfig-jdbc:tomcatRun
|
|
----
|
|
====
|
|
|
|
You should now be able to access the application at http://localhost:8080/
|
|
|
|
=== Exploring the `httpsession-jdbc` Sample Application
|
|
|
|
Now you can try using the application. To do so, fill out the form with the following information:
|
|
|
|
* *Attribute Name:* _username_
|
|
* *Attribute Value:* _rob_
|
|
|
|
Now click the *Set Attribute* button. You should now see the values displayed in the table.
|
|
|
|
=== How Does It Work?
|
|
|
|
We interact with the standard `HttpSession` in the `SessionServlet` shown in the following listing:
|
|
|
|
====
|
|
.src/main/java/sample/SessionServlet.java
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}spring-session-sample-javaconfig-jdbc/src/main/java/sample/SessionServlet.java[tags=class]
|
|
----
|
|
====
|
|
|
|
Instead of using Tomcat's `HttpSession`, we persist the values in H2 database.
|
|
Spring Session creates a cookie named `SESSION` in your browser.
|
|
That cookie contains the ID of your session.
|
|
You can view the cookies (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 remove the session by using the H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL).
|
|
|
|
Now you can visit the application at http://localhost:8080/ and see that the attribute we added is no longer displayed.
|