views:

94

answers:

3

Hi,

is there a way to chain several filters in a grails application (as in Java filters)? Maybe something with spring?

I've written a couple of filters, and would like to get them to execute serially (order is not particularly important), and I need some help on achieving this. The reason behind? I need to write about 20, 30 filters, and don't want them all in the same file.

I've read on spring's DelegatingFilterProxy but can't figure out on how to configure it to chain all my grails filters.

Any thoughts? An example would be greatly appreciated.

Thanks in advance.

+2  A: 

http://grails.org/doc/latest/guide/single.html#6.6.4%20Filter%20Dependencies

Blacktiger
right, but my filters have no dependencies between them, i just want them to execute serially.
Tom
@Tom: Well, doesn't that mean they are dependant on each other, just not with a specified order.
Esko
@Esko seems very very very untidy. As in trying to take advantage of a side efect.
Tom
@Esko Doesn't mean its not an option though.
Tom
Blacktiger is correct that the dependency declaration is the way to go. The thing to keep in mind is that Grails filters are wrappers around Spring HandlerInterceptors and are _not_ Servlet Filters. Servlet filters are typically chained but Grails filters are implicitly chained and are executed in the order declared in the Filters file. The dependency declaration lets you do exactly what you're asking - define multiple files but declare what order the files' filters run since it's somewhat nondeterministic without it - each files' filters run in order, but the file order isn't predictable.
Burt Beckwith
Probably the easiest thing to do is set up a fake dependency between them to ensure they run serially. Although perhaps they already do? Have you tested and found that they don't somehow? I would think they run serially but don't necessarily have an order.
Blacktiger
+1  A: 

I may not be understanding the core issue here, but the simple answer might be "they're already chained". Filters are executed based on the selector you put in the filter closure (e.g. myPreProcessorFilter(controller:'', action:'') {}). All selectors that match your controller/action will execute. I do this all the time with logging and performance measurement filters.

Here's an example. Both the logAction and measureMethodTime filters will be applied to all controllers and actions (since I left the selector wide open).

    import org.springframework.web.context.request.RequestContextHolder as RCH
import com.x.y.*

class PerformanceFilters {
    def filters = {

        logAction(controller:'*', action:'*'){
            before = {
                log.debug("${controllerName}.${actionName}: entering; params=${params}")
            }
        }

        measureMethodTime(controller:'*', action:'*'){
            before = {
                def session = RCH.currentRequestAttributes().getSession(false)
                if (session)
                {
                    Q.startTimer("${session.id}-${controllerName}-${actionName}", "method.${controllerName}.${actionName}")
                }
            }

            afterView = {
                def session = RCH.currentRequestAttributes().getSession(false)
                if (session)
                {
                    Q.stopTimer("${session.id}-${controllerName}-${actionName}", "method.${controllerName}.${actionName}")
                }
            }
        }

    }
}
ecodan
Yes, they are already chained. The things is that I have to write many many filters, and I dont want them to be all in the same file. Any way around that? Thanks
Tom
A: 

Since Grails 1.3.1 you can chain filters by using the "dependsOn" keyword:

def dependsOn = [MyOtherFilters.class]

http://jira.codehaus.org/browse/GRAILS-6229

david