在上一篇文章深入gin框架内幕(一)中,主要介绍了Gin框架中是如何创建一个HTTP服务以及内部的核心结构和常用的一些结构体方法,并在最后以一个简单的示例来详细讲解Gin框架内部具体是如何运行的,但是在最后我们会发现使用了一个
Context
引用对象的一些方法来返回具体的HTTP响应数据,在本篇文章中,我们将继续学习和分析Gin框架内幕。
在开始分析之前,我们先简单回顾一下上一个章节中讲到的Gin框架中的几个核心的结构.
Gin框架中的几个核心结构
Gin框架中的几个重要的模型:
Engine
: 用来初始化一个gin
对象实例,在该对象实例中主要包含了一些框架的基础功能,比如日志,中间件设置,路由控制(组),以及handlercontext等相关方法.源码文件Router
: 用来定义各种路由规则和条件,并通过HTTP服务将具体的路由注册到一个由context实现的handler中- Context:
Context
是框架中非常重要的一点,它允许我们在中间件间共享变量,管理整个流程,验证请求的json以及提供一个json的响应体. 通常情况下我们的业务逻辑处理也是在整个Context引用对象中进行实现的. - Bind: 在Context中我们已经可以获取到请求的详细信息,比如HTTP请求头和请求体,但是我们需要根据不同的HTTP协议参数来获取相应的格式化
数据来处理底层的业务逻辑,就需要使用Bind
相关的结构方法来解析context中的HTTP数据
1.Gin框架对HTTP响应数据的处理
我们在深入Gin框架内幕(一)中,以一个简单的Gin实例来具体讲解它内部是如何创建一个Http服务,并且注册一个路由来接收用户的请求,在示例程序中我们使用了Context
引用对象的String
方法来处理HTTP服务的数据响应,所以在整个Gin框架中紧跟Router
模型结构的就要属Context
结构了,该结构体主要用来处理整个HTTP请求的上下文数据,也是我们在开发HTTP服务中相对比较重要的一个结构体了。
# 深入Gin框架内幕(一)中的示例
$ cat case1.go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
ginObj := gin.Default()
ginObj.Any("/hello",func(c *gin.Context){
c.String(http.StatusOK,"Hello BGBiao.")
})
ginObj.Run("localhost:8080")
}
我们可以看到,在使用Gin框架后,我们只需要很简单的代码,即可以快速运行一个返回Hello BGBiao.
的HTTP服务,而在ginObj.Any
方法中,我们传入了一个参数为Context
引用类型的匿名函数,并在该函数内部采用String(code,data)
方法来处理HTTP服务的响应数据(返回Hello BGBiao字符串),这个时候,你可能会想,我们在企业内部都是前后端分离,通常情况下后端仅会提供RESTful API
,并通过JSON
格式的数据和前端进行交互,那么Gin是如何处理其他非字符串类型的数据响应呢,这也是我们接下来要主要讲的Context
结构模型。
2.Gin框架中的Context结构体
注意:
在Gin框架中由Router
结构体来负责路由和方法(URL和HTTP方法)的绑定,内的Handler采用Context
结构体来处理具体的HTTP数据传输方式,比如HTTP头部,请求体参数,状态码以及响应体和其他的一些常见HTTP行为。
Context结构体
:
type Context struct {
// 一个包含size,status和ResponseWriter的结构体
writermem responseWriter
// http的请求体(指向原生的http.Request指针)
Request *http.Request
// ResonseWriter接口
Writer ResponseWriter
// 请求参数[]{"Key":"Value"}
Params Params
handlers HandlersChain
index int8
// http请求的全路径地址
fullPath string
// gin框架的Engine结构体指针
engine *Engine
// 每个请求的context中的唯一键值对
Keys map[string]interface{}
// 绑定到所有使用该context的handler/middlewares的错误列表
Errors errorMsgs
// 定义了允许的格式被用于内容协商(content)
Accepted []string
// queryCache 使用url.ParseQuery来缓存参数查询结果(c.Request.URL.Query())
queryCache url.Values
// formCache 使用url.ParseQuery来缓存PostForm包含的表单数据(来自POST,PATCH,PUT请求体参数)
formCache url.Values
}
Context结构体常用的一些方法
基本方法
:
- Copy(): 返回当前正在使用的context的拷贝(context指针),当这个context必须在goroutine中用时,该方法比较有用
- HandlerName(): 返回当前主handler的名称(比如:handler为handleGetUsers(),该方法将返回"main.handleGetUsers"