In this post, we will learn how to implement session management using Spring Boot. For this tutorial we will be using MySQL 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.
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 MySQL as Session Management in Spring Boot
Apache Tomcat stores session objects in memory by default. For this example, we will be using MySQL database to store session objects by using Spring Session JDBC. It is pretty simple to tell Spring Boot to update the session storage type by updating the property:
spring.session.store-type=jdbc
Along with the properties, we need to import MySQL and Spring Session JDBC dependencies in pom.xml.
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
Let’s take an example.
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 JDBC, mysql and started JDBC. For this example we will be using thymleaf too for UI representation.
Thymleaf is a Java template engine for processing XML, XHTML and HTML5 in web and no-web environments. Spring provides full integration for thymleaf.
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.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rtech</groupId>
<artifactId>SessionManagement</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SessionManagement</name>
<description>Demo project for Spring Boot Session Management</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.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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 SQL as data source.
Configure MySQL
Update application.properties file.
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jdbcSession?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.initialization-mode=always
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
spring.session.timeout.seconds=1000
- spring.datasource.url is used to define database url. “jdbc:h2:mem:[your_database_name]” is how you define the url for H2
- spring.datasource.username and spring.datasource.password are the credentials to connect to database.
- 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.
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.sessionmanagement.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;
}
}
Add Templates and CSS for ThymeLeaf
For ThymeLeaf to work, a templates or HTML/CSS is required which is resolved in view mapping. These HTML file is defined inside resources/templates package and css inside resources/static package.
resources/home.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spring Boot Session Management</title>
<link th:href="@{/main.css}" rel="stylesheet">
</head>
<body>
<div>
<form th:action="@{/save}" method="post">
<textarea name="todo" cols="45" rows="2"></textarea>
<input class="text" type="submit" value="Add Todo" />
</form>
</div>
<div class="logout">
<form th:action="@{/logout}" method="post">
<input class ="submit" type="submit" value="Logout" />
</form>
</div>
<div>
<h2>Todos</h2>
<ul th:each="todo : ${todoList}">
<li><p>SessionId: <span th:text="${todo.id}"/>, Name:<span th:text="${todo.name}"/></p></li>
</ul>
</div>
</body>
</html>
resources/main.css
.logout {
margin-top: 20px;
}
.submit {
padding: 6px;
}
.text {
padding: 6px;
display: inherit;
}
Define Session Controller
package com.fullstack.coder.sessionmanagement.controller;
import com.fullstack.coder.sessionmanagementredis.model.Todo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
@Controller
public class SessionController {
@PostMapping("/save")
public String addTodo(@RequestParam("todo") 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 "redirect:/home";
}
@GetMapping("/home")
public String home(Model model, HttpSession session) {
List<Todo> todos = (List<Todo>) session.getAttribute("TODO_SESSION");
if (todos == null) {
todos = new ArrayList<>();
}
model.addAttribute("todoList", todos);
return "home";
}
@PostMapping("/logout")
public String logout(HttpServletRequest request) {
//clears session
request.getSession().invalidate();
return "redirect:/home";
}
}
SessionManagement Application
package com.fullstack.coder.sessionmanagement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
@SpringBootApplication
@EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 3000)
public class SessionManagementApplication {
public static void main(String[] args) {
SpringApplication.run(SessionManagementApplication.class, args);
}
}
@EnableJdbcHttpSession is used to tell Spring Boot that the application should store session information of the user.
Testing of Session Management
Project structure
Once you run the application, localhost:8080 can be visited through chrome or any browser. This is how your UI should looks like:
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 MySQL as datasource.