In this post, we will learn how to implement session management using Spring Boot. For this tutorial we will be using Redis as the data store for persisting Session information. Let’s get some overview of Session Management.

What is Session Management?

Http is a stateless protocol and any request made to the server with HTTP is treated as unique request. HTTP does not store session information of a user in it’s server and hence we need to find someway to store session information and improve user experience. Without storing session information, each request is treated as unique and user experience can be terrible as the user is not recognized.

Session Management comes to rescue. It is the mechanism of storing session information of each unique user in the web-based application. Due to this session, the server can distinguish between new user and visiting user which will improve user experience.

There are different ways for Session Management. Let’s look into few of them:

Cookies

There are the data saved on the computer in the form of some text files when a user makes some request to the server and a response is returned.

HTTPSession

Provides a way to store user or session information to identify user in the next subsequent request. This session can be stored in some kind of storage like MySQL, Redis and others.

There are others too like Hidden form field and URL Rewriting.

Redis

Reds is an in-memory key-value store where data can be stored and accessed at lighting speed. This is the reason that makes redis an ideal choice for enterprise caching. It can also be used for dealing with real time data or session management. It supports different kinds of data structures such as maps, sets, lists, strings and so on.

Setup Redis Locally

Nowadays, running image seems more convenient. To run image you must have Docker installed on your machine. Once Docker is installed and running just run the command:

docker run —d name my-redis-container -d redis

So, what this command does is, it will pull the latest image of redis and run it which means it will create a container or running instance of image. By default it will run on 6379 port.

However for this post, we will be setting up password too in redis using the following command:

docker run --name redis-test -p 6379:6379 -d --restart=always redis:latest redis-server --appendonly yes --requirepass "mypassword"
redis image run locally

Spring Session

Managing session information is critical mostly in distributed environment where there are multiple servers standing to serve request and load balancer before them. Now, let’s look into how to apply HTTP Session in Spring Boot. Spring Session has different modules as given below:

  • Spring Session Core: As the name suggest, it contains core functionalities for Spring Session
  • Spring Session Data Redis: Provides SessionRepository and ReactiveSessionRepository implementation backed by Redis support
  • Spring Session JDBC: Provides SessionRepository implementation backed by a relational database and configuration support
  • Spring Session Hazelcast: Provides SessionRepository implementation backed by a Hazelcast and configuration support
  • Spring Session MongoDB: Provides an API and implementations for managing a users session information stored in MongoDB by leveraging Spring Data MongoDB.

Configure Redis as Session Management in Spring Boot

Apache Tomcat stores session objects in memory by default. For this example, we will be using Redis database to store session objects by using Spring Session Data Redis. It is pretty simple to tell Spring Boot to update the session storage type by updating the property:

spring.session.store-type=redis

Along with the properties, we need to import Redis and Spring Session Redis dependencies in pom.xml.

		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-core</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-data-redis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

Let’s take an example.

Spring Boot Session Image

Setup Session Management in Spring Boot

Let’s use Spring Starter tool to generate a project with one click. You can add the dependencies we need while generating the project: Spring Web, Spring Session Core, Spring Session Redis and starter Redis.

Once you download the project, your pom should look like this:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.fullstack.coder</groupId>
	<artifactId>SessionManagementRedis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SessionManagementRedis</name>
	<description>Demo project for Spring Boot Session Management Redis</description>
	<properties>
		<java.version>11</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-core</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-data-redis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Configure Spring Boot Session Management

We need one more dependency for datasource. As i have mentioned above, you can use any datasource you like and for this part we will be using Redis as data source.

Configure Redis

Update application.properties file.

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=your passwd
spring.session.store-type=redis

#spring.session.timeout.seconds= # Session timeout. If a duration suffix is not specified, seconds is used.
spring.session.redis.flush-mode=on_save # Sessions flush mode.
spring.session.redis.namespace=spring:session
  • spring.session.timeout.seconds is used to set expiration time on session. By default the expiration time is 15 minutes. We can set the value as needed on the top of application with annotation.
  • spring.redis.host is the URL for redis. In our case it is localhost as i am running redis image locally.
  • spring.redis.port runs on 6379 by default.

Define Data Model class for Spring Session Management

Let’s take a simple example for Todo application. “id” stores sessionId of the user and “name” maps todo item.

ToDo

package com.fullstack.coder.sessionmanagementredis.model;

import java.io.Serializable;

public class Todo implements Serializable {
    String id;
    String name;

    public Todo(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Define Session Controller

package com.fullstack.coder.sessionmanagementredis.controller;

import com.fullstack.coder.sessionmanagementredis.model.Todo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@RestController
public class SessionController {


    @PostMapping("/save")
    public ResponseEntity<List<Todo>> addTodo(@RequestBody String todo, HttpServletRequest request) {

        HttpSession session = request.getSession();
        List<Todo> todos = (List<Todo>) session.getAttribute("TODO_SESSION");

        if (todos == null) {
            todos = new ArrayList<>();
        }
        todos.add(new Todo(session.getId(), todo));
        session.setAttribute("TODO_SESSION", todos);
        return new ResponseEntity<>(todos, HttpStatus.CREATED);
    }

    @GetMapping("/todos")
    public ResponseEntity<List<Todo>> home(HttpSession session) {
        List<Todo> todos = (List<Todo>) session.getAttribute("TODO_SESSION");
        if (todos == null) {
            todos = new ArrayList<>();
        }
        return new ResponseEntity<>(todos, HttpStatus.OK);
    }

    @DeleteMapping("/logout")
    public ResponseEntity<HttpStatus> logout(HttpServletRequest request) {
        //clears session
        request.getSession().invalidate();
        return new ResponseEntity<>(HttpStatus.OK);
    }
}

Session Application

package com.fullstack.coder.sessionmanagementredis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1500)
public class SessionManagementApplication {

	public static void main(String[] args) {
		SpringApplication.run(SessionManagementApplication.class, args);
	}

}

@EnableRedisHttpSession is used to tell Spring Boot that the application should store session information of the user in redis. maxInactiveIntervalInSeconds is to set time interval for expiration of session.

Testing of Session Management

Project Structure

Session Management Project Structure Redis Image

Once you run the application, localhost:8080 can be visited through postman.

postman: save todo request session management redis image

Conclusion

Spring Boot is amazing, most of the functionalities comes out of the box and just a tweak is needed. Similar is the case for session management. In this post we learnt how to configure session management in Spring Boot applications using Redis as datasource.