`
bloodwolf_china
  • 浏览: 131612 次
社区版块
存档分类
最新评论

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:'*"]和闭包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()
      }
}
分享到:
评论

相关推荐

    grails-fck-editor-0.3.zip_grails_grails-fck-editor

    标题中的"grails-fck-editor-0.3.zip_grails_grails-fck-editor"表明这是一个与Grails框架相关的插件,具体来说是FCKeditor的一个版本。FCKeditor是一款广泛使用的开源富文本编辑器,它允许用户在网页上创建和编辑...

    grails-datastore-gorm-plugin-support-2.0.4.RELEASE.zip

    总之,"grails-datastore-gorm-plugin-support-2.0.4.RELEASE.zip"提供了一个宝贵的资源,让开发者有机会学习和实践Grails的ORM功能和Android的MVC设计模式。无论是对Grails框架的探索,还是对Android开发的深化,这...

    grails-doc-CN-1.0.rar

    2. **Domain Class(领域模型)**:Grails 的核心概念之一是 Domain Class,它用于表示业务对象。这些类自动与数据库进行交互,通过 GORM(Grails Object-Relational Mapping)实现 ORM 功能。 3. **Controllers...

    groovy-grails-tool-suite-3.6.4.RELEASE-e4.4.2-win32-x86_64.part2

    groovy-grails-tool-suite-3.6.4.RELEASE-e4.4.2-win32-x86_64.part2 共两个包,解压后需要将扩展名.zip.bak改名为.zip重新解压。 http://dist.springsource.com/release/STS/3.8.1.RELEASE/dist/ e4.6/spring-tool-...

    Grails入门指南书籍和源码----下载不扣分,回帖加1分,欢迎下载,童叟无欺

    Grails入门指南书籍和源码----下载不扣分,回帖加1分,欢迎下载,童叟无欺 getting started with grails chinese Grails入门指南书籍和源码----下载不扣分,回帖加1分,欢迎下载,童叟无欺 getting started with ...

    grails 中文文档+grails-fckeditor-0.9.5.zip插件

    本文将深入探讨Grails的中文文档以及“grails-fckeditor-0.9.5”插件的相关知识点。 一、Grails框架基础 1. Groovy语言:Grails的基础是Groovy,这是一种面向对象、动态类型的编程语言,语法简洁且与Java高度兼容...

    groovy-grails-tool-suite-3.6.4.RELEASE-e4.4.2-win32-x86_64.part1

    groovy-grails-tool-suite-3.6.4.RELEASE-e4.4.2-win32-x86_64.part1 共两个压缩包,解压后将扩展名.zip.bak改为.zip再次解压。

    grails-web-url-mappings-2.5.4.zip

    《Grails Web URL Mappings 2.5.4:开源项目的URL路由艺术》 在Web开发领域,路由是连接用户请求与服务器响应的核心机制...而"grails-web-url-mappings-2.5.4.zip"的解压,为我们提供了研究和学习这一机制的宝贵资源。

    grails-3.0.5-ga (2/2)

    以下是关于"grails-3.0.5-ga (2/2)"的详细知识点: 1. **Groovy语言**: Grails框架是用Groovy语言编写的,这是一种动态、面向对象的编程语言,与Java高度兼容,但语法更加简洁和灵活。 2. **MVC架构**: Grails遵循...

    Grails-2.4.4-用户手册

    2. **创建新项目**:通过`grails create-app`命令创建项目,理解`grails-app`目录结构。 3. **编写Domain Class**:学习如何定义领域类,包括关系映射和验证规则。 4. **创建Controller**:了解如何创建控制器,处理...

    grails-docs-2.0.0

    `grails-docs-2.0.0`是Grails 2.0.0版本的官方文档,包含了丰富的指南、API参考以及国际化资源,对于学习和掌握Grails 2.0.0至关重要。 首先,`index.html`是文档的主页,通常会包含目录、介绍性内容以及如何开始的...

    grails-docs-1.0

    《Grails框架API文档详解——基于grails-docs-1.0》 Grails是一种基于Groovy语言的开源Web应用框架,它简化了Java开发,提供了丰富的功能和强大的工具,深受开发者喜爱。本文将深入探讨grails-docs-1.0版本的API...

    Grails入门指南 -- 针对grails1.0.4更新

    ### Grails入门指南知识点 #### 一、Grails框架简介 - **背景**: Grails是一个基于Groovy语言的开源Web应用框架,适用于Java平台。它旨在简化开发过程,提高开发效率,尤其受到那些希望保留Java环境同时寻求更高效...

    Grails入门指南-中文版

    Grails是一个高效的Web开发框架,它基于Groovy编程语言并构建在Spring、Hibernate和其他Java框架之上。这使得Grails成为一个一站式的解决方案,极大地提高了开发者的生产力。本文将详细介绍Grails的基本概念、核心...

    grails-acegi-0.5.zip

    4. `docs`、`grails-app`、`src`、`scripts`和`lib`目录则分别包含了插件的文档、应用代码、源代码、脚本以及依赖的库文件。 Grails Acegi 0.5插件提供了以下主要功能: - **用户认证**:支持多种认证机制,如...

    grails-spring-websocket

    grails-spring-websocket ils子 2.4.x 3.2.7+ 2.5.x 4.0.0+ 安装 要将插件安装到Grails应用程序中,请将以下行添加到build.gradle依赖项部分: implementation "org.grails.plugins:grails-spring-websocket:...

    grails-doc-1.0-beta1-中文.rar

    grails-doc-1.0-beta1-中文.rar。Grails 1.0 学习资料。

    grails-datastore-gorm-tck-1.0.9.RELEASE.zip

    标题 "grails-datastore-gorm-tck-1.0.9.RELEASE.zip" 提供的信息表明,这是一个与Grails框架相关的数据存储(Datastore)和GORM(Grails Object Relational Mapping)测试兼容性工具包(Test Compatibility Kit,...

    Grails开源框架 - 使用指南

    Grails开源框架 - 使用指南,版本1.0,中文文档。 Grails开源框架 - 使用指南 作者: Graeme Rocher, Marc Palmer 版本: 1.0 Copies of this document may be made for your own use and for distribution to ...

    grails-acegi-0.2.1.zip

    总的来说,“grails-acegi-0.2.1.zip”是一个研究Grails安全机制的良好起点,尤其是对于那些希望深入了解Grails权限管理和Spring Security集成的开发者来说,这个插件的源代码和配置文件提供了丰富的学习资源。

Global site tag (gtag.js) - Google Analytics