Filters are the middleware and are individual functions that make up therequest processing pipeline. They execute all of the framework’s functionality.

The Filter type is a simple function:

  1. typeFilterfunc(c*Controller,filterChain[]Filter)

Each filter is responsible for pulling the next filter off of the filter chainand invoking it. Below is the default filter stack:

  1. // The default set of global filters.// Can be set in an application on initialization.varFilters=[]Filter{PanicFilter,// Recover from panics and display an error page instead.RouterFilter,// Use the routing table to select the right ActionFilterConfiguringFilter,// A hook for adding or removing per-Action filters.ParamsFilter,// Parse parameters into Controller.Params.SessionFilter,// Restore and write the session cookie.FlashFilter,// Restore and write the flash cookie.ValidationFilter,// Restore kept validation errors and save new ones from cookie.I18nFilter,// Resolve the requested languageInterceptorFilter,// Run interceptors around the action.CompressFilter,// Compress the result.ActionInvoker,// Invoke the action.}

Filter chain configuration

Global configuration

Applications may configure the filter chain by re-assigning the revel.Filtersvariable in init(). By default this will be in app/init.go for a newlygenerated app.

  1. funcinit(){// The filters for my apprevel.Filters=[]Filter{PanicFilter,// Recover from panics and display an error page instead.RouterFilter,// Use the routing table to select the right ActionParamsFilter,// Parse parameters into Controller.Params.FilterConfiguringFilter,// A hook for adding or removing per-Action filters.SessionFilter,// Restore and write the session cookie.FlashFilter,// Restore and write the flash cookie.ValidationFilter,// Restore kept validation errors and save new ones from cookie.I18nFilter,// Resolve the requested languageInterceptorFilter,// Run interceptors around the action.CompressFilter,// Compress the result. [^1]ActionInvoker,// Invoke the action.}}

Every Request is sent down this chain, from top to bottom.

Per-Action configuration

Although all requests are sent down the revel.Filters chain, Revel alsoprovides aFilterConfigurator,which allows the developer to add, insert, or remove filter stages based on theAction or Controller.

This functionality is implemented by the FilterConfiguringFilter, itself afilter stage. For example to add a filter to all the actions for a MyController you can

  1. funcinit(){revel.FilterController(MyController{}).Insert(MyAuthFilter,revel.BEFORE,revel.ActionInvoker)}

Implementing a Filter

Keep the chain going

Filters are responsible for invoking the next filter to continue the requestprocessing. This is generally done with an expression as shown here:

  1. varMyFilter=func(c*revel.Controller,fc[]revel.Filter){// .. do some pre-processing ..fc[0](c,fc[1:])// Execute the next filter stage.// .. do some post-processing ..}

Getting the app Controller type

Filters receive the base Controller type as anargument, rather than the actual Controller type that was invoked. If yourfilter requires access to the actual Controller type that was invoked, it maygrab it with the following trick:

  1. varMyFilter=func(c*revel.Controller,fc[]revel.Filter){ifac,ok:=c.AppController.(*MyController);ok{// Have an instance of *MyController...}fc[0](c,fc[1:])// Execute the next filter stage.}

Note: this pattern is frequently an indicator thatinterceptors may be a better mechanism to accomplish thedesired functionality.

GoDoc Reference
GitHub Labels

原文: https://revel.github.io/manual/filters.html