网站首页 > 技术文章 正文
1 介绍
从前面的介绍可以了解到整个Gin由Engine、Route、Context等几个主要组成。Context是Gin框架中非常重要的一点,它允许我们在中间件间共享变量,管理整个流程,获取请求参数,渲染结果,通常情况下我们的业务逻辑处理也是在整个Context引用对象中进行实现的。Context的代码在context.go中实现。本文对Context的主要数据结构,主要的提供的方法进行概要的功能性介绍,后续章节则对每一部分进行详细的分析。
2 结构体说明
该Context主要实现了对Request和Response的封装以及一些参数的传递。其数据结构如下:
// Context is the most important part of gin. It allows us to pass variables between middleware,
// manage the flow, validate the JSON of a request and render a JSON response for example.
// Context是gin中最重要的部分。它允许我们在中间件中共享变量,管理流程,对请求中的JSON进行有效性检查并且渲染一个JSON的响应。
type Context struct {
writermem responseWriter // 响应处理
Request *http.Request // 请求信息
Writer ResponseWriter // 响应处理接口
Params Params // URL参数
handlers HandlersChain // 请求处理列表
index int8 // 用于对中间件进行流程控制
fullPath string // http请求的全路径地址
engine *Engine // gin框架的Engine结构体指针
params *Params
skippedNodes *[]skippedNode
// This mutex protect Keys map
// 对下面的Keys字段进行写保护的锁
mu sync.RWMutex
// Keys is a key/value pair exclusively for the context of each request.
// 元数据,用于在中间件中共享变量使用
Keys map[string]interface{}
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs
// Accepted defines a list of manually accepted formats for content negotiation.
Accepted []string
// queryCache use url.ParseQuery cached the param query result from c.Request.URL.Query()
// 管理解析后的Query参数
queryCache url.Values
// formCache use url.ParseQuery cached PostForm contains the parsed form data from POST, PATCH,
// or PUT body parameters.
// 管理解析后的Form参数
formCache url.Values
// SameSite allows a server to define a cookie attribute making it impossible for
// the browser to send this cookie along with cross-site requests.
sameSite http.SameSite
}
3 错误处理
- func(c *Context)Error(err error)*Error,将错误添加到上下文中
4 元数据管理
主要通过Keys map[string]interface{},在各个中间件中共享变量,提供的方法两类,Set和Get方法,只不过Get有很多变种,方便获取某种类型的数据。
函数 | 功能 |
Set(key string, value interface{}) | 给context设置一个新的键值对 |
Get(key string) (value interface{}, exists bool) | 返回指定的key的值,以及是否存在 |
MustGet(key string) interface{} | 返回指定key的值,不存在则panic |
GetString(key string) (s string) | 返回string类型 |
GetBool(key string) (b bool) | 返回bool类型 |
GetInt(key string) (i int) | 返回int类型 |
GetStringSlice(key string) (ss []string) | 返回一个字符串切片 |
GetStringMap(key string) (sm map[string]interface{}) | 返回一个map结构,类型为map[string]interface{} |
GetStringMapString(key string) (sms map[string]string) | 返回一个map结构,类型为map[string]string |
GetStringMapStringSlice(key string) (smss map[string][]string) | 返回一个map结构,类型为map[string][]string |
5 请求处理
5.1 获取参数
Context的主要功能之一就是对各种Request的参数进行解析和处理,当前Context主要支持URL Param、URL Query、PostForm、FormFile和MultipartForm等几类请求参数的类型,提供的主要方法如下表。
(1)URL Param,例如一个Restful API的定义为/user/:name,实际发送的请求是/user/john, 这个请求中name就是Param参数,参数值就是john
(2)URL Query,例如一个Restful API的定义为/getUserInfo?id=1234&age=18,这个请求中 id,age就是Query参数,参数值是1234,18
(3)PostForm,在POST请求的,请求体中发送的请求参数,例如下面是一个JSON格式的PostForm参数。
POST /post HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 18
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/3.1.0
{
"id": "1234",
"age": "18"
}
(4)FormFile,在POST请求中,主要用于上传文件,在Form中采用的是multipart/form-data编码方式,在下例子中上传了一个文件,参数为filename,值为py1.cfg,文件内容中也包含中请求体中。
POST /post HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 437
Content-Type: multipart/form-data; boundary=55315202afc745a99261513f37e7ffa2
Host: pie.dev
User-Agent: HTTPie/3.1.0
--55315202afc745a99261513f37e7ffa2
Content-Disposition: form-data; name="filename"; filename="py1.cfg"
home = d:\python\python37
implementation = CPython
version_info = 3.7.6.final.0
virtualenv = 20.0.7
include-system-site-packages = false
base-prefix = d:\python\python37
base-exec-prefix = d:\python\python37
base-executable = d:\python\python37\python.exe
prompt = (python_study)
--55315202afc745a99261513f37e7ffa2--
(5)MultipartForm,在POST请求中,除了上传文件外,还可以存储其它的参数。
函数 | 功能 |
Param(key string) string | 返回URL的Param参数值, |
Query(key string) string | 返回URL中的Query参数值 |
DefaultQuery(key, defaultValue string) string | 返回URL中的查询参数值,但是提供了一个默认值 |
QueryArray(key string) []string | 返回指定key的对应的数组切片 |
GetQueryArray(key string) ([]string, bool) | 同上,会返回状态 |
QueryMap(key string) map[string]string | 返回指定key对应map类型 |
GetQueryMap(key string) (map[string]string, bool) | 同上,会返回状态 |
PostForm(key string) string | 该方法返回一个从POST 请求的urlencode表单或者multipart表单数据,不存在时返回空字符串 |
DefaultPostForm(key, defaultValue string) string | 同上,key不存在时返回默认值 |
GetPostForm(key string) (string, bool) | 同PostForm()方法,并且会返回状态 |
PostFormArray(key string) []string | 该方法返回指定key的字符串类型的slice |
GetPostFormArray(key string) ([]string, bool) | 同上,并返回状态 |
PostFormMap(key string) map[string]string | 返回指定key的map类型 |
GetPostFormMap(key string) (map[string]string, bool) | 同上,并返回状态 |
FormFile(name string) (*multipart.FileHeader, error) | 返回指定key的第一个文件(用作文件上传) |
MultipartForm() (*multipart.Form, error) | 该方法解析multipart表单,包含file文件上传 |
SaveUploadedFile(file *multipart.FileHeader, dst string) error | 该方法用来上传指定的文件头到目标路径(dst) |
5.2 Bind函数
此组函数也是用于处理请求参数的,不过封装得更好,一方面能够直接将请求参数映射到一个结构体类型中,同时可以进行合法性检查,内置的有json, xml, protobuf, form, query, yaml。这些Bind极大的减少我们自己去解析各种个样的数据格式, 提高我们的开发速度,Bind的实现都在gin/binding里面。
- 这些方法底层使用MustBindWith;
- 如果存在绑定错误,请求将被以下指令中止 c.AbortWithError(400, err).SetType(ErrorTypeBind),响应状态代码会被设置为400,请求头Content-Type被设置为text/plain; charset=utf-8;
- 注意,如果你试图在此之后设置响应代码,将会发出一个警告 [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422,如果你希望更好地控制行为,请使用ShouldBind相关的方法。
函数 | 功能 |
Bind(obj interface{}) error | 自动解析Content-Type并绑定到指定的binding引擎 |
BindJSON(obj interface{}) error | 支持MIME为application/json的解析 |
BindXML(obj interface{}) error | 支持MIME为application/xml的解析 |
BindQuery(obj interface{}) error | 只支持QueryString的解析, 和Query()函数一样 |
BindYAML(obj interface{}) error | 支持MIME为application/x-yaml的解析 |
BindHeader(obj interface{}) error | |
BindUri(obj interface{}) error | 只支持路由变量的解析 |
MustBindWith(obj interface{}, b binding.Binding) error | 使用指定的binding引擎来绑定传递的结构体指针(当有任何错误时,终止请求并返回400) |
5.3 ShouldBind函数
类似于Bind函数,Context还提供了一组ShouldBind函数,这些方法底层使用ShouldBindWith,如果存在绑定错误,则返回错误,开发人员可以正确处理请求和错误。
6 Header处理
函数 | 功能 |
Status(code int) | 设置响应码 |
Header(key, value string) | (1)如果value不为空,则在响应体重写入一个header; |
GetHeader(key string) string | 返回请求体中的heade |
7 Cookie处理
- SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool): 该方法将设置一个Set-Cookie到响应头中;
- Cookie(name string) (string, error): 返回名称为name的cookie。
- 上一篇: 记一次简单的HTTP绕WAF 记一次拔河比赛400字
- 下一篇: 代码实现发邮件功能需要注意的问题
猜你喜欢
- 2024-11-08 加班用了2天,结果同事30分钟就搞定了?你和别人的差距在哪里
- 2024-11-08 下载文件工具类 文件下载工具是什么
- 2024-11-08 SMTP发送邮件 smtp发送邮件过程
- 2024-11-08 NPM 使用介绍 npm .staging
- 2024-11-08 java servlet笔记:设置编码集、文件下载和两种服务器跳转
- 2024-11-08 还不懂 HTTP 协议的吗?一篇文章讲透
- 2024-11-08 JavaScript包管理工具pnpm介绍 js importpackage
- 2024-11-08 Ajax请求时,请求类型,常用的几种 Content-Type json form-data xml
- 2024-11-08 Python教程:报表和日志精讲 python自动生成日报
- 2024-11-08 安全RCE之未授权访问分析 未授权的访问路径
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-