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

(Quick Reference) # 7.6.2 Filter Types - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.3.8 ## 7.6.2 Filter Types Within the body of the filter you can then define one or several of the following interceptor types for the filter: `before` - Executed before the action. Return `false` to indicate that the response has been handled that that all future filters and the action should not execute `after` - Executed after an action. Takes a first argument as the view model to allow modification of the model before rendering the view `afterView` - Executed after view rendering. Takes an Exception as an argument which will be non-`null` if an exception occurs during processing. Note: this Closure is called before the layout is applied. For example to fulfill the common simplistic authentication use case you could define a filter as follows:
    class SecurityFilters {
       def filters = {
           loginCheck(controller: '*', action: '*') {
               before = {
                  if (!session.user && !actionName.equals('login')) {
                      redirect(action: 'login')
                      return false
                   }
               }
           }
       }
    }
Here the `loginCheck` filter uses a `before` interceptor to execute a block of code that checks if a user is in the session and if not redirects to the login action. Note how returning false ensure that the action itself is not executed. Here's a more involved example that demonstrates all three filter types:

    import java.util.concurrent.atomic.AtomicLongclass LoggingFilters {   private static final AtomicLong REQUEST_NUMBER_COUNTER = new AtomicLong()
       private static final String START_TIME_ATTRIBUTE = 'Controller__START_TIME__'
       private static final String REQUEST_NUMBER_ATTRIBUTE = 'Controller__REQUEST_NUMBER__'   def filters = {      logFilter(controller: '*', action: '*') {         before = {
                if (!log.debugEnabled) return true            long start = System.currentTimeMillis()
                long currentRequestNumber = REQUEST_NUMBER_COUNTER.incrementAndGet()            request[START_TIME_ATTRIBUTE] = start
                request[REQUEST_NUMBER_ATTRIBUTE] = currentRequestNumber            log.debug "preHandle request #$currentRequestNumber : " +
                   "'$request.servletPath'/'$request.forwardURI', " +
                   "from $request.remoteHost ($request.remoteAddr) " +
                   " at ${new Date()}, Ajax: $request.xhr, controller: $controllerName, " +
                   "action: $actionName, params: ${new TreeMap(params)}"            return true
             }         after = { Map model ->            if (!log.debugEnabled) return true            long start = request[START_TIME_ATTRIBUTE]
                long end = System.currentTimeMillis()
                long requestNumber = request[REQUEST_NUMBER_ATTRIBUTE]            def msg = "postHandle request #$requestNumber: end ${new Date()}, " +
                          "controller total time ${end - start}ms"
                if (log.traceEnabled) {
                	log.trace msg + "; model: $model"
                }
                else {
                	log.debug msg
                }
             }         afterView = { Exception e ->            if (!log.debugEnabled) return true            long start = request[START_TIME_ATTRIBUTE]
                long end = System.currentTimeMillis()
                long requestNumber = request[REQUEST_NUMBER_ATTRIBUTE]            def msg = "afterCompletion request #$requestNumber: " +
                          "end ${new Date()}, total time ${end - start}ms"
                if (e) {
                   log.debug "$msg \n\texception: $e.message", e
                }
                else {
                   log.debug msg
                }
             }
          }
       }
    }
In this logging example we just log various request information, but note that the `model` map in the `after` filter is mutable. If you need to add or remove items from the model map you can do that in the `after` filter. | Quick Reference (hide)