Converting Http Session Events into Grails 3 Events

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}"
        }
    }
}

One thought on “Converting Http Session Events into Grails 3 Events”

  1. Just wanted to give my appreciation for this. Migrating an app from Grails 2.5 to Grails 3.2, and with all the multitude of changes, no one else seems to have addressed this particular scenario.

Leave a Reply

Your email address will not be published. Required fields are marked *