Revel 過(guò)濾器

2018-11-25 22:21 更新

過(guò)濾器是Revel框架的中間件 – 是組成請(qǐng)求處理管道的獨(dú)立的功能。他們執(zhí)行框架的所有功能。

過(guò)濾器類型是一個(gè)簡(jiǎn)單的函數(shù):

type Filter func(c *Controller, filterChain []Filter)

每個(gè)過(guò)濾器負(fù)責(zé)調(diào)用過(guò)濾器鏈中的下一個(gè)過(guò)濾器。下面是個(gè)默認(rèn)的過(guò)濾器棧:

// Filters 是默認(rèn)的全局過(guò)濾器集。
// 可以在程序初始化時(shí)設(shè)置它。
var Filters = []Filter{
    PanicFilter,             // 從恐慌中恢復(fù),并顯示一個(gè)錯(cuò)誤頁(yè)面。
    RouterFilter,            // 負(fù)責(zé)解析路由,并選擇正確的控制器方法。
    FilterConfiguringFilter, // 用于添加/刪除每個(gè)動(dòng)作過(guò)濾的鉤子。
    ParamsFilter,            // 解析參數(shù)到 Controller.Params 中。
    SessionFilter,           // 恢復(fù)和寫(xiě)入會(huì)話 cookie。
    FlashFilter,             // 恢復(fù)和寫(xiě)入 flash cookie。
    ValidationFilter,        // 恢復(fù)保存驗(yàn)證錯(cuò)誤并保存新的Cookie中。
    I18nFilter,              // 解析請(qǐng)求語(yǔ)言。
    InterceptorFilter,       // 執(zhí)行攔截器。
    ActionInvoker,           // 調(diào)用控制器。
}

過(guò)濾器鏈配置

全局配置

程序可以在 init() 中重寫(xiě) revel.Filters 變量,來(lái)配置過(guò)濾器鏈 (默認(rèn)在 app/init.go)。

func init() {
    // Filters 是默認(rèn)的全局過(guò)濾器集。
    revel.Filters = []Filter{
        PanicFilter,             // 從恐慌中恢復(fù),并顯示一個(gè)錯(cuò)誤頁(yè)面。
        RouterFilter,            // 負(fù)責(zé)解析路由,并選擇正確的控制器方法。
        FilterConfiguringFilter, // 用于添加/刪除每個(gè)動(dòng)作過(guò)濾的鉤子。
        ParamsFilter,            // 解析參數(shù)到 Controller.Params 中。
        SessionFilter,           // 恢復(fù)和寫(xiě)入會(huì)話 cookie。
        FlashFilter,             // 恢復(fù)和寫(xiě)入 flash cookie。
        ValidationFilter,        // 恢復(fù)保存驗(yàn)證錯(cuò)誤并保存新的Cookie中。
        I18nFilter,              // 解析請(qǐng)求語(yǔ)言。
        InterceptorFilter,       // 執(zhí)行攔截器。
        ActionInvoker,           // 調(diào)用控制器。
    }
}

每個(gè)請(qǐng)求沿著過(guò)濾器鏈從上到下依次執(zhí)行。

Per-Action configuration

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

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

實(shí)現(xiàn)一個(gè)過(guò)濾器

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

Filters 負(fù)責(zé)依次調(diào)用下一個(gè)過(guò)濾器來(lái)依次處理請(qǐng)求。這通常需要完成下面的表達(dá)式:

var MyFilter = func(c *revel.Controller, fc []revel.Filter) {
    // .. 做一些預(yù)處理 ..

    fc[0](c, fc[1:]) // 執(zhí)行下一個(gè)過(guò)濾器

    // .. 做一些后期處理 ..
}

獲取控制器類型

Filters 接受一個(gè) *Controller 類型的參數(shù), 而不是被調(diào)用的實(shí)際的控制器類型。如果過(guò)濾器需要訪問(wèn)實(shí)際的控制器類型,可以這樣實(shí)現(xiàn):

var MyFilter = func(c *revel.Controller, fc []revel.Filter) {
    if ac, err := c.AppController.(*MyController); err == nil {
        // 判定存在一個(gè) *MyController 實(shí)例...
    }

    fc[0](c, fc[1:]) // 執(zhí)行下一個(gè)過(guò)濾器
}

注意:這種模式往往說(shuō)明攔截器可能是實(shí)現(xiàn)所需功能的好的機(jī)制的一個(gè)指標(biāo)。

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)