|
|
|
# Context
|
|
|
|
|
|
|
|
以下是 blademaster 中 Context 对象结构体声明的代码片段:
|
|
|
|
```go
|
|
|
|
// Context is the most important part. It allows us to pass variables between
|
|
|
|
// middleware, manage the flow, validate the JSON of a request and render a
|
|
|
|
// JSON response for example.
|
|
|
|
type Context struct {
|
|
|
|
context.Context
|
|
|
|
|
|
|
|
Request *http.Request
|
|
|
|
Writer http.ResponseWriter
|
|
|
|
|
|
|
|
// flow control
|
|
|
|
index int8
|
|
|
|
handlers []HandlerFunc
|
|
|
|
|
|
|
|
// Keys is a key/value pair exclusively for the context of each request.
|
|
|
|
Keys map[string]interface{}
|
|
|
|
|
|
|
|
Error error
|
|
|
|
|
|
|
|
method string
|
|
|
|
engine *Engine
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
* 首先可以看到 blademaster 的 Context 结构体中会 embed 一个标准库中的 Context 实例,bm 中的 Context 也是直接通过该实例来实现标准库中的 Context 接口。
|
|
|
|
* Request 和 Writer 字段用于获取当前请求的与输出响应。
|
|
|
|
* index 和 handlers 用于 handler 的流程控制;handlers 中存储了当前请求需要执行的所有 handler,index 用于标记当前正在执行的 handler 的索引位。
|
|
|
|
* Keys 用于在 handler 之间传递一些额外的信息。
|
|
|
|
* Error 用于存储整个请求处理过程中的错误。
|
|
|
|
* method 用于检查当前请求的 Method 是否与预定义的相匹配。
|
|
|
|
* engine 字段指向当前 blademaster 的 Engine 实例。
|
|
|
|
|
|
|
|
以下为 Context 中所有的公开的方法:
|
|
|
|
```go
|
|
|
|
// 用于 Handler 的流程控制
|
|
|
|
func (c *Context) Abort()
|
|
|
|
func (c *Context) AbortWithStatus(code int)
|
|
|
|
func (c *Context) Bytes(code int, contentType string, data ...[]byte)
|
|
|
|
func (c *Context) IsAborted() bool
|
|
|
|
func (c *Context) Next()
|
|
|
|
|
|
|
|
// 用户获取或者传递请求的额外信息
|
|
|
|
func (c *Context) RemoteIP() (cip string)
|
|
|
|
func (c *Context) Set(key string, value interface{})
|
|
|
|
func (c *Context) Get(key string) (value interface{}, exists bool)
|
|
|
|
|
|
|
|
// 用于校验请求的 payload
|
|
|
|
func (c *Context) Bind(obj interface{}) error
|
|
|
|
func (c *Context) BindWith(obj interface{}, b binding.Binding) error
|
|
|
|
|
|
|
|
// 用于输出响应
|
|
|
|
func (c *Context) Render(code int, r render.Render)
|
|
|
|
func (c *Context) Redirect(code int, location string)
|
|
|
|
func (c *Context) Status(code int)
|
|
|
|
func (c *Context) String(code int, format string, values ...interface{})
|
|
|
|
func (c *Context) XML(data interface{}, err error)
|
|
|
|
func (c *Context) JSON(data interface{}, err error)
|
|
|
|
func (c *Context) JSONMap(data map[string]interface{}, err error)
|
|
|
|
func (c *Context) Protobuf(data proto.Message, err error)
|
|
|
|
```
|
|
|
|
|
|
|
|
所有方法基本上可以分为三类:
|
|
|
|
|
|
|
|
* 流程控制
|
|
|
|
* 额外信息传递
|
|
|
|
* 请求处理
|
|
|
|
* 响应处理
|
|
|
|
|
|
|
|
# Handler
|
|
|
|
|
|
|
|
![handler](/doc/img/bm-handlers.png)
|
|
|
|
|
|
|
|
初次接触 blademaster 的用户可能会对其 Handler 的流程处理产生不小的疑惑,实际上 bm 对 Handler 对处理非常简单。
|
|
|
|
将 Router 模块中预先注册的中间件与其他 Handler 合并,放入 Context 的 handlers 字段,并将 index 置 0,然后通过 Next() 方法一个个执行下去。
|
|
|
|
部分中间件可能想要在过程中中断整个流程,此时可以使用 Abort() 方法提前结束处理。
|
|
|
|
有些中间件还想在所有 Handler 执行完后再执行部分逻辑,此时可以在自身 Handler 中显式调用 Next() 方法,并将这些逻辑放在调用了 Next() 方法之后。
|
|
|
|
|
|
|
|
# 扩展阅读
|
|
|
|
|
|
|
|
[bm快速开始](blademaster-quickstart.md) [bm中间件](blademaster-mid.md) [bm基于pb生成](blademaster-pb.md)
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
[文档目录树](summary.md)
|