8.1.5 Controller Interceptors 2.4.4

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 8.1.5 Controller Interceptors - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.4.4 ## 8.1.5 Controller Interceptors Often it is useful to intercept processing based on either request, session or application state. This can be achieved with action interceptors. There are currently two types of interceptors: before and after. If your interceptor is likely to apply to more than one controller, you are almost certainly better off writing a Filter. Filters can be applied to multiple controllers or URIs without the need to change the logic of each controller #### Before Interception The `beforeInterceptor` intercepts processing before the action is executed. If it returns `false` then the intercepted action will not be executed. The interceptor can be defined for all actions in a controller as follows:
    def beforeInterceptor = {
        println "Tracing action ${actionUri}"
    }
The above is declared inside the body of the controller definition. It will be executed before all actions and does not interfere with processing. A common use case is very simplistic authentication:

    def beforeInterceptor = [action: this.&auth, except: 'login']// defined with private scope, so it's not considered an action
    private auth() {
        if (!session.user) {
            redirect(action: 'login')
            return false
        }
    }def login() {
        // display login page
    }
The above code defines a method called `auth`. A private method is used so that it is not exposed as an action to the outside world. The `beforeInterceptor` then defines an interceptor that is used on all actions except the login action and it executes the `auth` method. The `auth` method is referenced using Groovy's method pointer syntax. Within the method it detects whether there is a user in the session, and if not it redirects to the `login` action and returns `false`, causing the intercepted action to not be processed. #### After Interception Use the `afterInterceptor` property to define an interceptor that is executed after an action:
    def afterInterceptor = { model ->
        println "Tracing action ${actionUri}"
    }
The after interceptor takes the resulting model as an argument and can hence manipulate the model or response. An after interceptor may also modify the Spring MVC ModelAndView object prior to rendering. In this case, the above example becomes:
    def afterInterceptor = { model, modelAndView ->
        println "Current view is ${modelAndView.viewName}"
        if (model.someVar) modelAndView.viewName = "/mycontroller/someotherview"
        println "View is now ${modelAndView.viewName}"
    }
This allows the view to be changed based on the model returned by the current action. Note that the `modelAndView` may be `null` if the action being intercepted called `redirect` or `render`. #### Interception Conditions Rails users will be familiar with the authentication example and how the 'except' condition was used when executing the interceptor (interceptors are called 'filters' in Rails; this terminology conflicts with Servlet filter terminology in Java):
    def beforeInterceptor = [action: this.&auth, except: 'login']
This executes the interceptor for all actions except the specified action. A list of actions can also be defined as follows:
    def beforeInterceptor = [action: this.&auth, except: ['login', 'register']]
The other supported condition is 'only', this executes the interceptor for only the specified action(s):
    def beforeInterceptor = [action: this.&auth, only: ['secure']]
| Quick Reference (hide)