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()
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值