## 6.1.5 Controller Interceptors

Often it is useful to intercept processing based on either request, session or application state. This can be achieved via action interceptors. There are currently 2 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 however for authentication:

    def beforeInterceptor = [action:this.&auth,except:'login']
    // defined as a regular method so its private
    def auth() {
        if(!session.user) {
            redirect(action:'login')
            return false
        }
    }
    def login = {
        // display login page
    }

The above code defines a method called `auth`. A method is used so that it is not exposed as an action to the outside world (i.e. it is private). The `beforeInterceptor` then defines an interceptor that is used on all actions 'except' the login action and is told to execute the 'auth' method. The 'auth' method is referenced using Groovy's method pointer syntax, within the method itself it detects whether there is a user in the session otherwise it redirects to the login action and returns false, instruction the intercepted action not to be processed.

#### After Interception

To define an interceptor that is executed after an action use the `afterInterceptor` property:

    def afterInterceptor = { model ->
        println "Tracing action ${actionUri}"
    }

The after interceptor takes the resulting model as an argument and can hence perform post manipulation of 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 the servlet filter terminology in Java land):

    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 actions:

    def beforeInterceptor = [action:this.&auth,only:['secure']]