在之前的课程中说过,Beego的Context中,既有Input
又有Request
;既有Output
又有ResponseWriter
.很明显功能上是重叠的,道理上来讲,Input
和Request
留一个即可;Output
和ResponseWriter
留一个即可;或者将Request
放到Input
中,将ResponseWriter
放到Output
中.
type Context struct {
Input *BeegoInput
Output *BeegoOutput
Request *http.Request
ResponseWriter *Response
_xsrfToken string
}
这样的设计,对于使用者而言,很难理解Input
和Request
、Output
和ResponseWriter
之间的区别和各自的使用场景.
其中:
Input
:对输入的封装Output
:对输出的封装ResponseWriter
:对响应的封装
BeegoInput是对输入的封装
type BeegoInput struct {
Context *Context
CruSession session.Store
pnames []string
pvalues []string
data map[interface{}]interface{}
dataLock sync.RWMutex
RequestBody []byte
RunMethod string
RunController reflect.Type
}
BeegoInput.Context
:反向引用了Context
.而Context
中也通过Input
字段引用了BeegoInput
,这种A引用B同时B引用A的场景在GO中是比较常见的设计BeegoInput.CruSession
:耦合了SessionBeegoInput.pnames
:记录了参数路径的参数名BeegoInput.pvalues
:记录了参数路径的参数值BeegoInput.data
:记录了输入的数据(具体是啥我也不知道,没用过这个框架)BeegoInput.RequestBody
:若将web.Config.CopyRequestBody
设置为true,则框架会将原生的http.Request.Body
中的内容读到这个字段上
BeegoOutput是对输出的封装
// BeegoOutput does work for sending response header.
type BeegoOutput struct {
Context *Context
Status int
EnableGzip bool
}
BeegoOutput.Context
:同样反向引用了Context
BeegoOutput.Status
:HTTP响应码BeegoOutput.EnableGzip
:在写Response时是否启用Gzip压缩
type Response struct {
http.ResponseWriter
Started bool
Status int
Elapsed time.Duration
}
- 组合了原生的
http.ResponseWriter
Response.Started
:若该字段为true,则表示当前Response
结构体实例已经被写入过了
Context
中的Bind
族方法,用于将不同形式的Body
转化为具体的结构体.
Input.Bind()
方法用于将输入的一部分(通过key
参数指定)绑定到给定的dest
上(这个dest
可能是变量/map/结构体等).
这些方法负责从http.Request
的其他部位(例如Header、查询参数等)上获取输入
这里的GetData()
中的data指的是其他Beego内部的其他组件或Middleware向BeegoInput.data
中写入的数据
实际上这一类方法完全没必要提供,完全可以让用户自己判断,例如if method == http.MethodGet
的方式去判断.
这一类方法(Resp族的方法)将入参data
转化成对应的格式,然后输出到响应中
这一类方法是在web.Controller
结构体上的,用于渲染页面并输出
这一类方法是在context.BeegoOutput
结构体上的,实际上3.1小节中的Resp族的方法,最终调用的是BeegoOutput
上对应数据格式的方法.
而且,context.BeegoOutput
还有一些直接输出Body(Body()
方法)和Header(Header()
方法)的方法.
也就是说,写响应时,可以使用Context
,也可以使用Context.BeegoOutput
,看自己喜好即可.当然,这也会导致框架的使用者会有不同的风格来控制输出.