過濾器是Revel框架的中間件 – 是組成請求處理管道的獨立的功能。他們執(zhí)行框架的所有功能。
過濾器類型是一個簡單的函數(shù):
type Filter func(c *Controller, filterChain []Filter)
每個過濾器負(fù)責(zé)調(diào)用過濾器鏈中的下一個過濾器。下面是個默認(rèn)的過濾器棧:
// Filters 是默認(rèn)的全局過濾器集。
// 可以在程序初始化時設(shè)置它。
var Filters = []Filter{
PanicFilter, // 從恐慌中恢復(fù),并顯示一個錯誤頁面。
RouterFilter, // 負(fù)責(zé)解析路由,并選擇正確的控制器方法。
FilterConfiguringFilter, // 用于添加/刪除每個動作過濾的鉤子。
ParamsFilter, // 解析參數(shù)到 Controller.Params 中。
SessionFilter, // 恢復(fù)和寫入會話 cookie。
FlashFilter, // 恢復(fù)和寫入 flash cookie。
ValidationFilter, // 恢復(fù)保存驗證錯誤并保存新的Cookie中。
I18nFilter, // 解析請求語言。
InterceptorFilter, // 執(zhí)行攔截器。
ActionInvoker, // 調(diào)用控制器。
}
程序可以在 init()
中重寫 revel.Filters
變量,來配置過濾器鏈 (默認(rèn)在 app/init.go
)。
func init() {
// Filters 是默認(rèn)的全局過濾器集。
revel.Filters = []Filter{
PanicFilter, // 從恐慌中恢復(fù),并顯示一個錯誤頁面。
RouterFilter, // 負(fù)責(zé)解析路由,并選擇正確的控制器方法。
FilterConfiguringFilter, // 用于添加/刪除每個動作過濾的鉤子。
ParamsFilter, // 解析參數(shù)到 Controller.Params 中。
SessionFilter, // 恢復(fù)和寫入會話 cookie。
FlashFilter, // 恢復(fù)和寫入 flash cookie。
ValidationFilter, // 恢復(fù)保存驗證錯誤并保存新的Cookie中。
I18nFilter, // 解析請求語言。
InterceptorFilter, // 執(zhí)行攔截器。
ActionInvoker, // 調(diào)用控制器。
}
}
每個請求沿著過濾器鏈從上到下依次執(zhí)行。
盡管所有的請求都被發(fā)往過濾器鏈 revel.Filters
, Revel 也提供了 過濾器配置
, 允許開發(fā)者根據(jù)操作或控制器添加、插入、刪除過濾器。
此功能通過 FilterConfiguringFilter
實現(xiàn), 它本身就是一個過濾器.
Filters 負(fù)責(zé)依次調(diào)用下一個過濾器來依次處理請求。這通常需要完成下面的表達(dá)式:
var MyFilter = func(c *revel.Controller, fc []revel.Filter) {
// .. 做一些預(yù)處理 ..
fc[0](c, fc[1:]) // 執(zhí)行下一個過濾器
// .. 做一些后期處理 ..
}
Filters 接受一個 *Controller
類型的參數(shù), 而不是被調(diào)用的實際的控制器類型。如果過濾器需要訪問實際的控制器類型,可以這樣實現(xiàn):
var MyFilter = func(c *revel.Controller, fc []revel.Filter) {
if ac, err := c.AppController.(*MyController); err == nil {
// 判定存在一個 *MyController 實例...
}
fc[0](c, fc[1:]) // 執(zhí)行下一個過濾器
}
注意:這種模式往往說明攔截器可能是實現(xiàn)所需功能的好的機制的一個指標(biāo)。
更多建議: