Monday, February 5, 2007

Grails -- Interceptors in Grails

Introduction

An Interceptor is one of the key components in Aspect-Oriented Programming (AOP). It is defined to intercept method invocations, constructor invocation and field access. In grails, there are only two types of interceptor: beforeInterceptor and afterInterceptor. They both are action interceptors used inside controllers.

Examples

befoerIntercetor

This simple interceptor intercepts an user's request and checks uploaded file content-type. If it is not a PDF file, then it redirects the user to a previous view and presents an error message and returns false to caller. The innovation of the method is terminated; If yes, it continues the method call and trigger an action. It is very easy to use, no any configuration is needed.

class myController {
def update = {/** do something here **/}
def save = {/** do something here **/}

//This line defines which actions is going to be intercepted.
def beforeInterceptor = [action:this.&validateFileType,only:['update', 'save']]

def validateFileType = {
def myFile= request.getFile("myFile") //get uploaded file
if (myFile!=null && !(myFile.isEmpty()))
{
def contentType = f.getContentType()
if (contentType!="application/pdf"){
flash.message = "File must be a valid PDF file"
redirect(action:create) //if fails, redirect to previous page.
return false //This will terminate method call
}
else {
...
...
return true
}
}
else {
...
...
return true
}
}
}

In the line

def beforeInterceptor = [action:this.&validateFileType,only:['update', 'save']]

"only" is called “condition”. The condition of an interceptor can be either "only" or "except". If the condition is not defined, then all actions in the controller will be intercepted.

afterInceptor

The second interceptor is afterInterceptor. Unlike beforeInterceptor, afterInterceptor gets invoked after an action has executed and before response gets back to client. We can process response object inside afterInterceptor before it gets back to clients, for example, writing logs, compressing files, sending emails, etc.

The usage of afterInterceptor is very similar to that of beforeInterceptor. In my previous posting Grail -- How to Send Out Email After Some Actions Have Been Finished, I have posted an afterInterceptor example. I would like to save some space here.

Commentary

In grails, it is quite easy to use action interceptors to intercepts process based on either request or response. And it is also quite flexible to define which actions would trigger interceptors. No any XML configuration needed, which is the promise of coding by convention.

However, there are still some limitations here. As I know for the time being, an interceptor can only intercepts actions from the same controller instead of multiple controllers. In other words, no interceptor chain is supported in Grails current releases. Despite of this, I still want to say: the interceptors are so cool!

References

Grails Tutorial#Controllers (http://grails.codehaus.org/Controllers)

2 comments:

Tom Gullo said...

I didn't get the 'return false' to short circuit a controller until I read your post. Thanks

Anonymous said...

It was extremely interesting for me to read this blog. Thank you for it. I like such themes and everything that is connected to this matter. I definitely want to read a bit more soon.
Alex
Phone jammers