Go Revel - Filters(过滤器链)

Fitlers过滤器链是一个中间件,它们具有单独的功能,并作为管道对请求做链式处理。过滤器链执行框架的所有功能。

对过滤器链的源码分析,请移步 Go Revel - Filter(过滤器)源码分析 http://www.cnblogs.com/hangxin1940/p/3266311.html

一个过滤器这样定义:

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

没一个过滤器负责拉取下一个过滤器并执行它。下面是所有过滤器的调用堆栈:

var Filters = []Filter{
    PanicFilter,             // 运行时异常过滤器    恢复一个 panics 运行时异常并且显示异常信息页面
    RouterFilter,            // 路由过滤器       根据路由器选择正确的Action
    FilterConfiguringFilter, // 自定义过滤器配置器       为每一个Action增加或删除自定义过滤器
    ParamsFilter,            // 参数转换过滤器 将请求的参数转换为 Controller.Params
    SessionFilter,           // 会话过滤器       恢复和写入会话cookie
    FlashFilter,             // Flash过滤器        恢复和写入Flash信息cookie
    ValidationFilter,        // 验证过滤器       恢复保存验证错误并且从cookie中新建一个
    I18nFilter,              // i18n过滤器     解析请求的语言
    InterceptorFilter,       // 拦截器过滤器      在Action前后运行拦截器
    ActionInvoker,           // Action过滤器       调用Action方法
}

golang_filters

配置过滤器链

全局配置

应用程序可以在init()方法内重新分配revel.Filters变量中的过滤器顺序。(在使用revel生成新的应用时会在app/init.go中构造默认的过滤器链)

func init() {

    revel.Filters = []Filter{
        PanicFilter,             // 运行时异常过滤器    恢复一个 panics 运行时异常并且显示异常信息页面
        RouterFilter,            // 路由过滤器       根据路由器选择正确的Action
        FilterConfiguringFilter, // 自定义过滤器配置器       为每一个Action增加或删除自定义过滤器
        ParamsFilter,            // 参数转换过滤器 将请求的参数转换为 Controller.Params
        SessionFilter,           // 会话过滤器       恢复和写入会话cookie
        FlashFilter,             // Flash过滤器        恢复和写入Flash信息cookie
        ValidationFilter,        // 验证过滤器       恢复保存验证错误并且从cookie中新建一个
        I18nFilter,              // i18n过滤器     解析请求的语言
        InterceptorFilter,       // 拦截器过滤器      在Action前后运行拦截器
        ActionInvoker,           // Action过滤器       调用Action方法
    }
}

每一个请求都会按从上到下的顺序交给每个过滤器处理。

每个Action的配置

尽管所有请求都沿着revel.Filters过滤器链向下运行,但是revel也提供了FilterConfigurator,允许围绕controlleraction方便的对其添加、插入和删除自定义过滤器栈。

FilterConfiguringFilter实现了这些功能,而且它本身就是一个过滤器栈。

实现一个过滤器

保持管道链的继续运行

过滤器负责调用下一个过滤器来继续对请求的处理。

var MyFilter = func(c *revel.Controller, fc []revel.Filter) {
    // .. 在调用之前做些处理 ..

    fc[0](c, fc[1:]) // 执行下一个过滤器栈.

    // .. 逐个退出过滤器栈 ..
}

获取Controller控制器类型

过滤器将*Controller类型作为地一个传入的参数,而不是实际调用的 Controller 类型,如果过滤器需要对实际调用的controller进行操作,可以使用如下技巧:

var MyFilter = func(c *revel.Controller, fc []revel.Filter) {
    if ac, err := c.AppController.(*MyController); err == nil {
        // 取得一个 *MyController 实例...
    }

    fc[0](c, fc[1:]) // 执行下一个过滤器栈
}

posted on   黑暗伯爵  阅读(978)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示