Spring Session + Redis + Servlet Integration Example
February 01, 2017
This page will walk through Spring session, Redis and Servlet integration example. By default a java web application uses servlet container to save session values. Spring session can externalize the persistence of session attributes values. We can use external source to save and fetch session ids. Here in our example we are using Redis. Session id will be stored as keys in Redis. Spring session replaces the HttpSession
implementation by a custom implementation. To perform this task spring session creates a SessionRepositoryFilter
bean named as springSessionRepositoryFilter. Spring Session with Redis works as follows.
1. Spring session exposes a
SessionRepositoryFilter
bean named as springSessionRepositoryFilter.
2. The bean springSessionRepositoryFilter is responsible to replace Servlet container
HttpSession
implementation by custom implementation such as Redis.
3. To use
HttpSession
backed by Redis using JavaConfig, Spring session provides @EnableRedisHttpSession
annotation that will be annotated at java configuration class. @EnableRedisHttpSession
exposes SessionRepositoryFilter
bean named as springSessionRepositoryFilter .
4. To use
HttpSession
backed by Redis using XML configuration, Spring session provides RedisHttpSessionConfiguration
class. We need to create a bean of this class in our spring application context XML file. RedisHttpSessionConfiguration
exposes SessionRepositoryFilter
bean named as springSessionRepositoryFilter .
5.To get connection with Redis, we need to create a bean of
RedisConnectionFactory
implementation. If we are using Lettuce then create the bean of LettuceConnectionFactory
class in both cases JavaConfig as well as XML configuration.
6.When we run java servlet application and save values in session then it will not be saved in Tomcat Servlet container. Now the session values will be saved in Redis. Spring session creates a cookie with name SESSION instead of JSESSIONID in the browser.
Here we will provide complete example of spring session with servlet using Redis. We will use JavaConfig as well as XML configuration in our demo.
Contents
- Software Used
- Redis Installation
- Project Structure in Eclipse with JavaConfig
- Gradle and Maven to Build Project
- Create Sample Servlet and JSP File for Spring Session Demo
- Create JavaConfig for LettuceConnectionFactory with @EnableRedisHttpSession
- Create Application Initializer with AbstractHttpSessionApplicationInitializer
- Project Structure in Eclipse with XML
- Create Spring Application Context XML File for RedisHttpSessionConfiguration and LettuceConnectionFactory
- Create web.xml
- Run Application
- References
- Download Source Code
Software Used
Find the software used in our demo.1. Java 8
2. Redis 2.8.17
3. Spring 4
4. Tomcat 8.0.12
5. Eclipse Mars
Redis Installation
To work with Spring Session using Redis, we need to install Redis in our system. Find the below steps to install Redis.1. Go to the link and download the Redis. If operating system is Windows then visit the link. Minimum required version of Redis for Spring Session is redis-2.8.
2. Extract the archive file and go to the location as below.
\redis-2.8\bin\release\redis-2.8.17
3. Click on redis-server.exe to start the Redis server. Server will be started with default port 6379.
4. To run Redis command, click on the redis-cli.exe file. A command prompt will open and we can run the Redis command. For Redis command details visit the link.
5. Find some Redis commands.
a. To display all keys stored in Redis, use keys *
b. To delete all keys stored in Redis, use flushall
Project Structure in Eclipse with JavaConfig
Find the project structure in Eclipse with JavaConfig.
Gradle and Maven to Build Project
Find the gradle file to build the project.build.gradle
apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'war' archivesBaseName = 'spring-session' version = '0.0.1-SNAPSHOT' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter-web:1.4.3.RELEASE' compile 'org.springframework.session:spring-session-data-redis:1.3.0.RELEASE' compile 'biz.paluch.redis:lettuce:3.5.0.Final' compile 'jstl:jstl:1.2' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.4.3.RELEASE' }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.concretepage</groupId> <artifactId>spring-session</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>spring-session</name> <description>Spring Project</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.3.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.3.0.RELEASE</version> </dependency> <dependency> <groupId>biz.paluch.redis</groupId> <artifactId>lettuce</artifactId> <version>3.5.0.Final</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> </dependencies> </project>
Create Sample Servlet and JSP File for Spring Session Demo
We will create sample Servlet and JSP file for spring session demo.HomeServlet.java
package com.concretepage; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/home") public class HomeServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String attributeName = req.getParameter("attributeName"); String attributeValue = req.getParameter("attributeValue"); //add attribute in HttpSession req.getSession().setAttribute(attributeName, attributeValue); resp.sendRedirect(req.getContextPath() + "/"); } }
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="en"> <head> <title>Spring Session with Servlet</title> </head> <body> <h3>Add Session Attribute</h3> <form action="./home" method="POST"> Attribute Name : <input type="text" name="attributeName"/><br/> Attribute Value : <input type="text" name="attributeValue"/><br/><br/> <input type="submit" value="Add Attribute"/> </form> <c:if test="${sessionScope.size() gt 0}"> <h3>Session Attribute Details</h3> <table> <tr> <th>Attribute Name</th> <th>Attribute Value</th> </tr> <c:forEach items="${sessionScope}" var="attb"> <tr> <td><c:out value="${attb.key}"/></td> <td><c:out value="${attb.value}"/></td> </tr> </c:forEach> </table> </c:if> </body> </html>
setAttribute()
of HttpSession
. But values are not being persisted in Tomcat Servlet container. Session values are being persisted in Redis. Spring session creates a cookie named as SESSION in browser that contains the id of our session.
Create JavaConfig for LettuceConnectionFactory with @EnableRedisHttpSession
Lettuce is an advanced Redis client that is used for thread safe synchronous, asynchronous and reactive usage. It supports Cluster, Sentinel, Pipelining, and codecs. Lettuce allows sharing one connection by multiple threads if they avoid blocking.AppConfig.java
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @EnableRedisHttpSession public class AppConfig { @Bean public LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); } }
LettuceConnection
instance for every call of getConnection()
method of LettuceConnectionFactory
class. Multiple LettuceConnection
instances share a single thread safe native connection by default. This shared native connection is never closed by the LettuceConnection
instance and hence while calling getConnection()
method, connection is not validated by default. If required we can change this behavior by using setValidateConnection(true)
method of LettuceConnectionFactory
while instantiating it.
@EnableRedisHttpSession: This annotation is added to configuration class. Using this annotation, it automatically adds
@Configuration
to the configuration class. It exposes a bean of SessionRepositoryFilter
with bean name springSessionRepositoryFilter
that will be backed by Redis. We have also to provide RedisConnectionFactory
implementation bean. In our example we are using Lettuce based connection, so we have created a bean of LettuceConnectionFactory
class.
Create Application Initializer with AbstractHttpSessionApplicationInitializer
To load our application configurationAppConfig
class, find the application initializer class.
AppInitializer.java
package com.concretepage; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; public class AppInitializer extends AbstractHttpSessionApplicationInitializer { public AppInitializer() { super(AppConfig.class); } }
AbstractHttpSessionApplicationInitializer
is the implementation of spring WebApplicationInitializer
interface. It performs following task.
1. It registers
DelegatingFilterProxy
to use springSessionRepositoryFilter before any other registered Filter
.
2. It also registers spring
ContextLoaderListener
.
3. It ensures that our servlet will use
springSessionRepositoryFilter
for every request that is responsible for replacing HttpSession
implementation by custom implementation backed by Redis.
Project Structure in Eclipse with XML
Find the project structure in Eclipse with XML configuration.
Create Spring Application Context XML File for RedisHttpSessionConfiguration and LettuceConnectionFactory
Find spring application context XML file to configure spring session.app-config.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/> <bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/> </beans>
RedisHttpSessionConfiguration
exposes a bean of SessionRepositoryFilter
with bean name springSessionRepositoryFilter
backed by Redis. SessionRepositoryFilter
implements Filter
and replaces the HttpSession
implementation to be backed by Spring Session.
2. We should use
<context:annotation-config/>
because Spring Session does not provide Spring XML Namespace configuration right now. Get more information from the link .
3. Create a bean of
LettuceConnectionFactory
that implements RedisConnectionFactory
. The role of RedisConnectionFactory
is connecting Spring Session to Redis Server on default port 6379 .
Create web.xml
Create web.xml file.web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Spring Session with Servlet</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/app-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> </web-app>
app-config.xml
in our example, we need to configure contextConfigLocation
using <context-param>
. Configure ContextLoaderListener
that will read contextConfigLocation and will pick up our app-config.xml
file.
2. In
app-config.xml
file we have configured RedisHttpSessionConfiguration
that exposes a bean of SessionRepositoryFilter
with bean name springSessionRepositoryFilter
backed by Redis, responsible for replacing the HttpSession
implementation to be backed by Spring Session. Now we need to ensure that Servlet Container uses our springSessionRepositoryFilter
for every request. So we need to configure springSessionRepositoryFilter
mapping.
3. Spring
DelegatingFilterProxy
will look up a bean with the name springSessionRepositoryFilter
that casts a filter backed by Spring Session. Hence for every request that invokes DelegatingFilterProxy
will invoke springSessionRepositoryFilter
.
Run Application
To run the project, follow below steps.1. Download the source code using download link given below on this page.
2. Using command prompt, go to the root directory of the project and run following command. For Gradle, use below command.
gradle clean build
We will get WAR file inside build\libs directory. For Maven, use below command.
mvn clean package
We will get WAR file inside target directory. Now deploy WAR file in tomcat and access the URL as follows.
http://localhost:8080/spring-session/
Add some session attribute names and values. Find the print screen.



I am done now. Happy Spring Session Learning!
References
Spring Session - HttpSession (JavaConfig)Spring Session - HttpSession (XML Configuration)