浏览 2258 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-11-11
最后修改:2008-11-11
class TestFilters { def log ={ before = { println "Before Filter" } } def filters = { //这儿的方法名doFilter不重要,可以随便命名,为了调用闭包而已 doFilter([controller: '*', action: '*',uri:'*'],log) } } DefaultGrailsFiltersClass.groovy class DefaultGrailsFiltersClass extends AbstractInjectableGrailsClass implements GrailsFiltersClass { static FILTERS = "Filters"; //grails类必须的构造函数,可以让FiltersGrailsPlugin找到 DefaultGrailsFiltersClass(Class aClass) { super(aClass, FILTERS) } public List getConfigs(Object filters) { if (!filters) return []; def loader = new Loader(filters) //找到TestFilters的filters闭包属性 def filtersClosure = filters.filters filtersClosure.delegate = loader //调用闭包即doFilter([controller: '*', action: '*',uri:'*"],log),生成FilterConfig对象数组 filtersClosure.call() return loader.filters; } } class Loader { def filtersDefinition def filters = [] Loader(filtersDefinition) { this.filtersDefinition = filtersDefinition } //调用闭包即filter([controller: '*', action: '*',uri:'*"],log) //methodName=doFilter,args是[controller: '*', action: '*',uri:'*"]和闭包log def methodMissing(String methodName, args) { if(args) { def fc = new FilterConfig(name: methodName, filtersDefinition: filtersDefinition) filters << fc if(args[0] instanceof Closure) { fc.scope = [ uri: '/**' ] def closure = args[0] closure.delegate = fc closure.call() } else if(args[0] instanceof Map) { fc.scope = args[0] if(args.size() > 1 && args[1] instanceof Closure) { def closure = args[1] closure.delegate = fc //args[1]即是TestFilters的log闭包,调用对象delegate是FilterConfig closure.resolveStrategy = Closure.DELEGATE_FIRST //log闭包调用的第一句就是before= {...},而FilterConfig就有一个before的闭包属性 //这样fc.before即为TestFilters中的before闭包,fc.scope即为[controller: '*', action: '*',uri:'*"] closure.call() } } fc.initialised = true } } } FilterConfig.groovy class FilterConfig { String name Map scope Closure before Closure after Closure afterView ... } 再看看FilterToHandlerAdapter进行FilterConfig到HandlerInterceptor的适配就很简单了,检查FilterConfig是否有before,after和afterView属性,再用scope属性验证当前ruquest的uri,controller和action FilterToHandlerAdapter.groovy //检查grails的controllerName,actionName,uri是否 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) { if (filterConfig.before) { String controllerName = controllerName(request) String actionName = actionName(request) String uri = uri(request) if (!accept(controllerName, actionName, uri)) return true; def callable = filterConfig.before.clone() def result = callable.call(); if(result instanceof Boolean) { if(!result && filterConfig.modelAndView) { renderModelAndView(filterConfig, request, response, controllerName) } return result } } return true; } boolean accept(String controllerName, String actionName, String uri) { if (controllerRegex == null || actionRegex == null) { def scope = filterConfig.scope if (scope.controller) { controllerRegex = Pattern.compile(scope.controller.replaceAll("\\*", ".*")) } else { controllerRegex = Pattern.compile(".*") } if (scope.action) { actionRegex = Pattern.compile(scope.action.replaceAll("\\*", ".*")) } else { actionRegex = Pattern.compile(".*") } if (scope.uri) { uriPattern = scope.uri.toString() } } if(uriPattern) { return pathMatcher.match(uriPattern, uri) } else if(controllerRegex && actionRegex) { return controllerRegex.matcher(controllerName).matches() && actionRegex.matcher(actionName).matches() } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |