3

In the Grails 'Upgrading from 2.x to 3.0.6' document it's been noted that "new servlets and filters can be registered as Spring beans or with ServletRegistrationBean and FilterRegistrationBean respectively" however not much else is said on the matter.

I am wondering if anybody has any good input on how to do this properly (i.e., using the init/BootStrap.groovy which contains the servlet context to load beans, versus beans in conf/spring) or perhaps there is some pre-defined Spring way of doing this that's obvious and I am missing.

Note: I am trying to integrate spring-ws into Grails 3.0.6.

chrisburke.io
  • 1,497
  • 2
  • 17
  • 26

2 Answers2

6

You should do this in doWithSpring for a plugin, or grails-app/conf/spring/resources.groovy for an app. Since Grails 3 is based on Spring Boot you can also use an @Bean method.

When the application context starts up, Spring looks for ServletRegistrationBeans, FilterRegistrationBeans, etc. and uses their configured properties to do programmatic registration in the servlet container for you.

There are some examples in the Grails source. ControllersGrailsPlugin registers some filters (e.g. here) and the main dispatcher servlet is registered here.

There's some documentation in the Spring Boot docs although it's biased towards @Bean methods, but you can use any approach to defining the beans.

Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156
2

(Works for Grails 3 (specifically version 3.3.3))

To add custom listener to servletContext by using "doWithSpring" section of plugin descriptor file (*GrailsPlugin.groovy):

Step #1

*GrailsPlugin.groovy

...
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean
import my.custom.listeners.ContextListener
...
class MyAppGrailsPlugin extends Plugin {
...
    Closure doWithSpring() {
        {->
        ...
        httpSessionServletListener(ServletListenerRegistrationBean){
            listener = bean(ContextListener)
        }
        ...
    }
...
}

Step #2: Now it can be referred in e.g. service classes as:

SomeService.groovy

class SomeService{        
    ...
    def httpSessionServletListener
    ...
    def someMethod(){
        httpSessionServletListener.getSessions()
    }
    ...
}

Step #0: Custom filter class should be written

Here is the snippet of custom listener class implementing respective interface:

ContextListener.groovy

import javax.servlet.http.HttpSession
import javax.servlet.http.HttpSessionListener

public class ContextListener implements HttpSessionListener {
    ...
    /**
     * All current sessions.
     */
    public List<HttpSession> getSessions() {
        synchronized (this) {
            return new ArrayList<HttpSession>(sessions)
        }
    }
    ...
}
Alex Uke
  • 143
  • 1
  • 3