多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
过滤器是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)可能是实现所需功能的好的机制的一个指标。