首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

grails源码分析-之Filters机制(二)

2012-10-26 
grails源码分析---之Filters机制(2)我们写一个Filters跟踪分析一下Filters是如何变化加入到CompositeInter

grails源码分析---之Filters机制(2)
我们写一个Filters跟踪分析一下Filters是如何变化加入到CompositeInterceptor的handlers成员
   

    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:'*"]和闭包logdef 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()      }}

热点排行