= Spring Session - HttpSession (Quick Start)
Rob Winch, Vedran Pavić
:toc:

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: The completed guide can be found in the <<httpsession-jdbc-sample, httpsession-jdbc sample application>>.

== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
If you are using Maven, ensure to 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-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.
Ensure you 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 ensure to add the Spring Milestone Maven Repository.
Ensure you 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.
Add the following Spring Configuration:

[source,java]
----
include::{samples-dir}javaconfig/jdbc/src/main/java/sample/Config.java[tags=class]
----

<1> The `@EnableJdbcHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.
The filter is what 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 H2 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].

== Java Servlet Container Initialization

Our <<httpsession-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 (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` both of these steps extremely easy.
You can find an example below:

.src/main/java/sample/Initializer.java
[source,java]
----
include::{samples-dir}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`.
This ensures that the Spring Bean by the name `springSessionRepositoryFilter` is registered with our Servlet Container for every request.
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily ensure Spring loads our `Config`.

// end::config[]

[[httpsession-jdbc-sample]]
== 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 :samples:httpsession-jdbc:tomcatRun
----

You should now be able to access the application at http://localhost:8080/

=== Exploring the httpsession-jdbc Sample Application

Try using the application. 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 below:

.src/main/java/sample/SessionServlet.java
[source,java]
----
include::{samples-dir}javaconfig/jdbc/src/main/java/sample/SessionServlet.java[tags=class]
----

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]).

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)

Now visit the application at http://localhost:8080/ and observe that the attribute we added is no longer displayed.
