Go Revel - Interceptors(拦截器)
`interceptor`拦截器是revel框架在执行一个`action`的前后所调用的函数。他允许以AOP方式进行开发,这种模式非常有用:
1、记录请求日志
2、错误处理
3、状态保持
在revel中,可以使用两种形式的拦截器:
1、函数拦截器:
一个满足`InterceptorFunc`接口的函数,它不会访问任何一个特定的`controller`调用;可以被应用到任意/所有的`controller`上
2、方法拦截器:
一个无参且返回`revel.Result`类型的`controller`方法,它只会拦截已绑定的`controller`;可以随意的修改调用的`controller`
拦截器按它们的添加顺序执行。
##拦截时间
拦截器可以注册并运行在一个请求的四种生命周期:
1、`BEFORE`: 请求被路由之后,session、flash与参数已经被正确的解码,但是还没有调用`action`
2、`AFTER`: 一个请求已经返回`Result`对象, 但是还没用应用这个`Result`,即执行`action`之后。如果`action`发生`panic`,则这些拦截器不会被调用
3、`PANIC`: 在`action`发生`panic`后,或者处理`Result`时抛出异常
4、`FINALLY`: `action`被成功执行并且`Result`被正确处理之后
##Results返回值
拦截器通常返回`nil`,这种请跨下,拦截器将会继续往下执行。
各时段调用拦截器返回非空`revel.Result`时所产生的效果:
1、`BEFORE`: 不会再执行任何拦截器,包括action
2、`AFTER`: 所有的拦截器将会继续运行
3、`PANIC`: 所有的拦截器将会继续运行
4、`FINALLY`: 所有的拦截器将会继续运行
在所有情况下,任何`Result`返回值都将会代替现有的`Result`
然而,在`BEFORE`阶段,`Result` 返回值为最终的`Result`, 而在`AFTER`阶段,拦截器可能会生成自己的`Result`
##示例
**函数拦截器**
下面演示了如何定义并注册一个函数拦截器:
func (c Hotels) checkUser() revel.Result {
if user := connected(c); user == nil {
c.Flash.Error("Please log in first")
return c.Redirect(App.Index)
}
return nil
}
func init() {
revel.InterceptMethod(Hotels.checkUser, revel.BEFORE)
}
**方法拦截器**
一个方法拦截器必需符合下面两种形式的签名:
func (c AppController) example() revel.Result
func (c *AppController) example() revel.Result
下面演示了只针对controller操作的拦截器:
func checkUser(c *revel.Controller) revel.Result {
if user := connected(c); user == nil {
c.Flash.Error("Please log in first")
return c.Redirect(App.Index)
}
return nil
}
func init() {
revel.InterceptFunc(checkUser, revel.BEFORE, &Hotels{})
}