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