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{})
}
浙公網安備 33010602011771號