Revel 過濾器

2018-11-25 22:21 更新

過濾器是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í)行。

Per-Action configuration

盡管所有的請求都被發(fā)往過濾器鏈 revel.Filters, Revel 也提供了 過濾器配置, 允許開發(fā)者根據(jù)操作或控制器添加、插入、刪除過濾器。

此功能通過 FilterConfiguringFilter 實現(xiàn), 它本身就是一個過濾器.

實現(xiàn)一個過濾器

保持過濾器鏈能夠依次執(zhí)行

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)。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號