In this post of Spring Boot, we will look at the Spring Boot session listener or Spring Boot HttpSessionListner. This post will walk you through the steps to create and register HttpSessionListener with our spring boot application.
Introduction
The HttpSessionListener provides notification when an HTTP session is created and destroyed. To use it, we need to implement sessionCreated()
and sessionDestroyed()
methods. The #sessionCreated()
method invoked when a new session is created while #sessionDestroyed()
triggers on either session time out or when the session got invalidated using #invalidate()
method. To create a Http session listener in Spring Boot, we need to create a bean of HttpSessionListener.
1. Maven Setup
Let’s create a simple web application by adding spring-boot-starter-web starter in our pom.xml
file. This is how our pom.xml
file will look like:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.javadevjournal</groupId>
<artifactId>session-listener</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>session-listener</name>
<description>Spring Boot Session Listener Example</description>
<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.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>
2. HttpSessionListener Implementation
Let’s see how to create our custom HttpSessionListener. In our implementation, we will keep trek of each new session creation and will update our counter when the session destroyed or getting invalided.
@WebListener
public class CustomSessionListner implements HttpSessionListener {
private static final Logger LOG= LoggerFactory.getLogger(CustomSessionListner.class);
private final AtomicInteger counter = new AtomicInteger();
@Override
public void sessionCreated(HttpSessionEvent se) {
LOG.info("New session is created. Adding Session to the counter.");
counter.incrementAndGet(); //incrementing the counter
updateSessionCounter(se);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
LOG.info("Session destroyed. Removing the Session from the counter.");
counter.decrementAndGet(); //decrementing counter
updateSessionCounter(se);
}
private void updateSessionCounter(HttpSessionEvent httpSessionEvent){
//Let's set in the context
httpSessionEvent.getSession().getServletContext()
.setAttribute("activeSession", counter.get());
LOG.info("Total active session are {} ",counter.get());
}
}
This is a simple code. We are keeping trek of all the active session using AtomicInteger .Every time a new session created; we are incrementing the count and on session invalidation; we are decrementing. In our example we are using the @WebListener
annotation.If you like, you can create a simple Spring bean by using @Bean
annotation. To use @WebListner
annotation with our Spring Boot application, we need to add @ServletComponentScan
with @SpringBootApplication annotation.
3. Simple REST Controller
Let’s create a simple REST controller to test our application.
@RestController
public class SessionDemoController {
private static final Logger LOG = LoggerFactory.getLogger(SessionDemoController.class);
@GetMapping("/get-session-count")
public String testSessionListner(HttpServletRequest request, HttpServletResponse response){
HttpSession session = request.getSession(false);
if(session == null){
LOG.info("Unable to find session. Creating a new session");
session = request.getSession(true);
}
return "Session Test completed";
}
}
4. Spring Boot Main Class
To Run our application, let’s add the Spring Boot main class. This is how it look like:
@ServletComponentScan
@SpringBootApplication
public class SessionListenerApplication {
public static void main(String[] args) {
Spring application.run(SessionListenerApplication.class, args);
}
}
We are using the @ServletComponentScan
annotation to enable scanning for @WebListener
.If we run our application, you might see similar output:
2019-06-17 23:17:28.969 INFO 13763 --- [nio-8080-exec-1] c.j.controller.SessionDemoController : Unable to find session. Creating a new session
2019-06-17 23:17:28.986 INFO 13763 --- [nio-8080-exec-1] c.j.listener.CustomSessionListner : it creates New session. Adding Session to the counter.
2019-06-17 23:17:28.986 INFO 13763 --- [nio-8080-exec-1] c.j.listener.CustomSessionListner : Total active session are 1
2019-06-17 23:17:34.841 INFO 13763 --- [nio-8080-exec-3] c.j.controller.SessionDemoController : Unable to find session. Creating a new session
2019-06-17 23:17:34.841 INFO 13763 --- [nio-8080-exec-3] c.j.listener.CustomSessionListner : we create New session. Adding Session to the counter.
2019-06-17 23:17:34.842 INFO 13763 --- [nio-8080-exec-3] c.j.listener.CustomSessionListner : Total active session are 2
4. Use of HttpSessionListner
We should customize the HttpSessionListner when we want to customize the session handling. Here are some use cases when we like to create a custom HttpSessionListner in Spring Boot application.
- Setting the session time out (
HttpSession.setMaxInactiveInterval()
). - We like to cleanup specific resources on session close.Use
HttpSession.sessionDestroyed()
method for this.
Summary
In this article we saw Spring Boot HttpSessionListner. We look at the option to create a custom HttpSessionListner along with details as when we should think about creating a custom session listener for our application. As always, the source code for this post is available on the GitHub.