Grails 3 introduced a new Events API based on Reactor. Unfortunately, as far as I can tell, HttpSessionEvents are not natively part of the Grails 3 Events system. Bringing them in to the fold, however, is pretty easy. I based this off of Oliver Wahlen's immensely helpful blog post about sending the HttpSessionEvents to a Grails service.
First, let's create our Spring HttpSessionServletListener. Create this file somewhere in the /src/ path where Grails will find it:
File: .../grailsProject/src/main/groovy/com/example/HttpSessionServletListener.groovy
package com.example import grails.events.* import javax.servlet.http.HttpSession import javax.servlet.http.HttpSessionEvent import javax.servlet.http.HttpSessionListener class HttpSessionServletListener implements HttpSessionListener, Events { // called by servlet container upon session creation void sessionCreated(HttpSessionEvent event) { notify("example:httpSessionCreated", event.session) } // called by servlet container upon session destruction void sessionDestroyed(HttpSessionEvent event) { notify("example:httpSessionDestroyed", event.session) } }
Now register the HttpSessionServletListener as a Spring Bean. If you don't already have a resources.groovy file, create one and add the following.
.../grailsProject/grails-app/conf/spring/resources.groovy
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean import com.example.HttpSessionServletListener beans = { httpSessionServletListener(ServletListenerRegistrationBean) { listener = bean(HttpSessionServletListener) } } // Yes this is the entire file
Now you are all set to listen for the "example:httpSessionCreated" and "example:httpSessionDestroyed" events using the Grails 3 Events API. "Example" is the namespace of the event, which in my real code I set to the last part of the package name, so I made it match the package name of "example". Just use something so you don't have to worry about naming collisions.
Here's an example of listening for the events in a standard Grails Controller. Note that the event handlers are attached after construction, and before the Controller bean is made available, by using the PostConstruct annotation.
.../grailsProject/grails-app/controllers/com/example/ExampleController.groovy
package com.example import grails.events.* import javax.annotation.PostConstruct class ExampleController { @PostConstruct void init() { on("example:httpSessionCreated") { session -> println "sessionCreated: ${session.id}" } on("example:httpSessionDestroyed") { session -> println "sessionDestroyed: ${session.id}" } } }