为你自己学Go
  • README
  • PART01.Web框架概览
    • 1.01 Web框架概览:学习路线
    • 1.02 Web框架概览-Beego框架分析
    • 1.03 Web框架概览-GIN框架分析
    • 1.04 Web框架概览-Iris框架分析
    • 1.05 Web框架概览-Echo框架分析
  • PART02.Server
    • 2.01 Server详解与面试要点
  • PART03.路由树
    • 3.01 路由树-Beego&GIN&Echo实现与设计总结
    • 3.02 路由树-全静态匹配
    • 3.03 路由树-TDD起步
    • 3.04 路由树-静态匹配测试用例
    • 3.05 路由树-静态匹配之路由查找
    • 3.06 路由树-静态匹配之集成Server
    • 3.07 路由树-通配符匹配之路由注册
    • 3.08 路由树-通配符匹配之路由查找与测试
    • 3.09 路由树-参数路径之基本注册和查找
    • 3.10 路由树-参数路径之校验
    • 3.11 路由树-参数路径之参数值
    • 3.12 路由树-总结与面试要点
  • PART04.课后复习
    • 4.01 课后复习-Server
    • 4.02 课后复习-Route
  • PART05.Context
    • 5.01 Context-简介
    • 5.02 Context-Beego Context设计分析
    • 5.03 Context-Gin Context设计分析
    • 5.04 Context-Echo和Iris的Context设计分析
    • 5.05 Context-处理输入输出总结
    • 5.06 Context-处理输入之Body输入
    • 5.07 Context-处理输入之表单输入
    • 5.08 Context-处理输入之查询参数、路径参数和StringValue
    • 5.09 Context-处理输出
    • 5.10 Context-总结与面试要点
  • PART06.AOP
    • 6.01 AOP简介与不同框架设计概览
    • 6.02 AOP设计方案-Middleware
  • PART07.Middleware
    • 7.01 Middleware-AccessLog
    • 7.02 Middleware-Trace简介和OpenTelemetry
    • 7.03 Middleware-OpenTelemetry测试
    • 7.04 Middleware-OpenTelemetry总结
    • 7.05 Prometheus详解
    • 7.06 Middleware-Prometheus
    • 7.07 Middleware-错误页面
    • 7.08 Middleware-从panic中恢复
    • 7.09 Middleware总结和面试
  • PART08.Review
    • 8.01 课后复习-AOP
    • 8.02 课后复习-Context
    • 8.03 课后复习-Middleware-AccessLog
  • PART09.Appendix
    • 附录1.责任链模式
    • 附录2.生成器模式
    • 附录3.函数选项模式
  • xiaochengxu
    • 01.原力去水印
    • 02.KeePass密码管理:安全轻松的管理您的密码
Powered by GitBook
On this page
  • PART1. Beego Context设计
  • 1.1 Context
  • 1.2 BeegoInput
  • 1.3 BeegoOutput
  • 1.4 Response
  • PART2. Beego 处理输入的方法
  • 2.1 负责处理来自http.Request.Body输入的方法
  • 2.2 负责处理来自其他部位的方法
  • 2.3 各种判断的方法
  • PART3. Beego 处理输出的方法
  • 3.1 将输入序列化之后输出的方法
  • 3.2 渲染模板输出的方法
  • 3.3 输出各种格式数据的方法
  1. PART05.Context

5.02 Context-Beego Context设计分析

Last updated 9 months ago

PART1. Beego Context设计

1.1 Context

在之前的课程中说过,Beego的中,既有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:对响应的封装

1.2 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:耦合了Session

  • BeegoInput.pnames:记录了参数路径的参数名

  • BeegoInput.pvalues:记录了参数路径的参数值

  • BeegoInput.data:记录了输入的数据(具体是啥我也不知道,没用过这个框架)

1.3 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压缩

1.4 Response

type Response struct {
	http.ResponseWriter
	Started bool
	Status  int
	Elapsed time.Duration
}
  • 组合了原生的http.ResponseWriter

  • Response.Started:若该字段为true,则表示当前Response结构体实例已经被写入过了

PART2. Beego 处理输入的方法

2.1 负责处理来自http.Request.Body输入的方法

2.1.1 Context的Bind族方法

Context中的Bind族方法,用于将不同形式的Body转化为具体的结构体.

2.1.2 Input的Bind()方法

2.2 负责处理来自其他部位的方法

这些方法负责从http.Request的其他部位(例如Header、查询参数等)上获取输入

这里的GetData()中的data指的是其他Beego内部的其他组件或Middleware向BeegoInput.data中写入的数据

2.3 各种判断的方法

实际上这一类方法完全没必要提供,完全可以让用户自己判断,例如if method == http.MethodGet的方式去判断.

PART3. Beego 处理输出的方法

3.1 将输入序列化之后输出的方法

这一类方法(Resp族的方法)将入参data转化成对应的格式,然后输出到响应中

3.2 渲染模板输出的方法

这一类方法是在web.Controller结构体上的,用于渲染页面并输出

3.3 输出各种格式数据的方法

这一类方法是在context.BeegoOutput结构体上的,实际上3.1小节中的Resp族的方法,最终调用的是BeegoOutput上对应数据格式的方法.

而且,context.BeegoOutput还有一些直接输出Body(Body()方法)和Header(Header()方法)的方法.

也就是说,写响应时,可以使用Context,也可以使用Context.BeegoOutput,看自己喜好即可.当然,这也会导致框架的使用者会有不同的风格来控制输出.

是对输入的封装

BeegoInput.RequestBody:若将设置为true,则框架会将原生的http.Request.Body中的内容读到这个字段上

是对输出的封装

方法用于将输入的一部分(通过key参数指定)绑定到给定的dest上(这个dest可能是变量/map/结构体等).

Context
BeegoInput
web.Config.CopyRequestBody
BeegoOutput
Response
Input.Bind()
Beego处理输入的方法-Bind族
BeegoInput中负责从其他部位获取输入的方法
BeegoInput中负责从其他部位获取输入的方法-2
Input中各种判断的方法
Context中处理序列化输出的方法
Controller中渲染模板输出的方法
Output中定义输出各种格式数据的方法