In this article I show how to store the HTTP session into Redis with Spring Boot. I show the necessary dependencies and how to configure Spring Boot to not have the HTTP session stored only in the application.
Content
- the usage of the HTTP session in a Spring Boot application;
- the necessary dependencies to store the HTTP session into Redis;
- how to make an object serializable;
- how to configure the connexion between Spring Boot and Redis.
Watch this video for more details.
All the code of the article is available in this repository.
Stateful Application
Having the session in the controllers allows me to store more information about the requests. But this also means that the requests have a state, that i’m in a stateful application. Nowadays, we used to fear the HTTP session because it’s a meaning of a stateful application.
When starting the communication with the Spring Boot application, i can specify that a session can be created. This will return me a cookie to identify the session. In this session i can store whatever information i want. Which will help the application register all the transactions previously done by the user. This way, the application already knows the user, not only by its credentials but also by its previous actions.
Consequently, the information sent on each request can be slightly lower. I don’t need to indicate all the history of the transaction made by the user to reproduce an action. This information is already stored in the session.
This is very useful when i build a basket. I can add items of the user in its basket without finalizing the sale. The information about the added items will remain on the session until the user finishes the transaction.
On the other side, without the session, i need to store somewhere all the items the user added to the basket. It can be in the database or maintaining all this information on each request. Of course, there are some inconvenience. But let’s see first how to create a session for each request.
Http Session
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling().authenticationEntryPoint(userAuthenticationEntryPoint)
.and()
.addFilterBefore(new UsernamePasswordAuthFilter(), BasicAuthenticationFilter.class)
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/v1/signIn", "/v1/signUp").permitAll()
.anyRequest().authenticated();
}
With the line sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS), I indicate that each request will ALWAYS create a new session if it doesn’t exist. That’s all.
@GetMapping("/messages")
public ResponseEntity<List<MessageDto>> getCommunityMessages(
@AuthenticationPrincipal UserDto user,
@RequestParam(value = "nextPage", defaultValue = "false") boolean nextPage,
HttpSession session) {
Integer currentPage = (Integer) session.getAttribute("currentPageMessages");
if (currentPage == null) {
currentPage = 0;
}
if (nextPage) {
currentPage++;
}
session.setAttribute("currentPageMessages", currentPage);
return ResponseEntity.ok(communityService.getCommunityMessages(user, currentPage));
}
Now, in a controller, I can have the input parameter HttpSession to read the information stored in the session per user.
In this controller, the sessions contains the information about the current page to be read. The front end only needs to know that the user wants to load the next page. And in the session, I increment the value of the page read.
The session information is stored in the Spring Boot application. It can be identified per user depending on the value present in a cookie created by the Spring Security context.
But here comes the hidden face of a stateful application. What happens if for some reason my application restarts?
Redis
How to solve this? Serializing the session and storing it somewhere. Where? In Redis? Why? Redis is a key value storage service and it is known to be very performant to get the value from a single key. In my case, i have the id of the session, this can be the key, and the session itself can be the value. So, i have to make my user information serializable to be stored in Redis. And i have to tell Spring Boot where to save the session. For that, i need two dependencies: one to tell Spring Boot about the connection with Redis; and the other to tell how to serialize the user information of the session into 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>
Now, configure my objets to be serializable. I only need to make my objects implement the Serializable interface.
public class UserDto implements Serializable {
...
Implementing this interface, Java knows that this object can be serializable, can be formatted into a string. And finally, configure Spring Boot with the connection to Redis.
spring:
redis:
host: localhost
port: 6379
session:
store-type: redis
Conclusion
To have the benefits of a stateless application but maintain the user session, i need:
- The user object to be serializable;
- A place to store the user object, in this case Redis;
- Add the two dependencies, to serialize the user object to Redis, and to connect my application to Redis;
- And finally add the connection information to Redis into my configuration file.
This way, having the user session serialized into Redis, i can have the benefits of a stateless application, as the redundant servers, the failsafe application, etc.



Leave a comment