gin 框架中的 gin.Context

〇、前言

Context 是 gin 中最重要的部分。 例如,它允许我们在中间件之间传递变量、管理流程、验证请求的 JSON 并呈现 JSON 响应。

Context 中封装了原生的 Go HTTP 请求和响应对象,同时还提供了一些方法,用于获取请求和响应的信息、设置响应头、设置响应状态码等操作。

在 Gin 中,Context 是通过中间件来传递的。在处理 HTTP 请求时,Gin 会依次执行注册的中间件,每个中间件可以对 Context 进行一些操作,然后将 Context 传递给下一个中间件。

一、gin.Context 结构

type Context struct {writermem responseWriterRequest   *http.RequestWriter    ResponseWriterParams   Paramshandlers HandlersChainindex    int8fullPath stringengine       *Engineparams       *ParamsskippedNodes *[]skippedNode// 该互斥锁保护键映射。mu sync.RWMutex// Keys 是专门用于每个请求上下文的键/值对。Keys map[string]any// 错误是附加到使用此上下文的所有处理程序/中间件的错误列表。Errors errorMsgs// 已接受定义了用于内容协商的手动接受格式的列表。Accepted []string// queryCache 缓存 c.Request.URL.Query() 的查询结果。queryCache url.Values// formCache 缓存 c.Request.PostForm,其中包含从 POST、PATCH 或 PUT 正文参数解析的表单数据。	formCache url.Values// SameSite 允许服务器定义 cookie 属性,从而使浏览器无法随跨站点请求发送此 cookie。sameSite http.SameSite
}

这里面需要重点关注的的几个字段就是:

	writermem responseWriterRequest   *http.RequestWriter    ResponseWriterParams    Paramsparams    *Params

1、writermem responseWriter

type responseWriter struct {http.ResponseWritersize   intstatus int
}

responseWriter 包含了一个 interface 类型 ResponseWriter:

type ResponseWriter interface {// Header returns the header map that will be sent by WriteHeader.Header() Header// Write writes the data to the connection as part of an HTTP reply.Write([]byte) (int, error)// WriteHeader sends an HTTP response header with the provided status code.WriteHeader(statusCode int)
}

2、Request *http.Request

Request 表示服务器接收到并由客户端发送的 HTTP 请求,这也是一个复杂的结构:

type Request struct {Method           stringURL              *url.URLProto            stringProtoMajor       intProtoMinor       intHeader           HeaderBody             io.ReadCloserGetBody          func() (io.ReadCloser, error)ContentLength    int64TransferEncoding []stringClose            boolHost             stringForm             url.ValuesPostForm         url.ValuesMultipartForm    *multipart.FormTrailer          HeaderRemoteAddr       stringRequestURI       stringTLS              *tls.ConnectionStateCancel           <-chan struct{}Response         *Responsectx              context.Context
}

可以看到里面提供了各种我们常用的字段:

	Method           stringURL              *url.URLHeader           HeaderHost             stringForm             url.ValuesPostForm         url.ValuesResponse         *Responsectx              context.Context

看到这里有一个 *Response:

type Response struct {Status           stringStatusCode       intProto            stringProtoMajor       intProtoMinor       intHeader           HeaderBody             io.ReadCloserContentLength    int64TransferEncoding []stringClose            boolUncompressed     boolTrailer          HeaderRequest          *RequestTLS              *tls.ConnectionState
}

关于:Response是导致创建此请求的重定向响应,该字段仅在客户端重定向期间填充。看到这儿就放心了,不然也太繁杂了。

关于 Context:上下文携带截止日期、取消信号和跨 API 边界的其他值。 Context 的方法可以同时被多个 goroutine 调用。

context.Context:是 Go 标准库中的一个接口类型,用于在 Goroutine 之间传递上下文信息。

context.Context 可以在 Goroutine 之间传递信息,例如传递请求 ID、数据库连接、请求超时等信息。context.Context 的具体实现是由各种库和框架提供的,Gin 框架中提供了一个 gin.Context 的实现,用于在 Gin 框架中使用 context.Context。

type Context interface {// 返回时间Deadline() (deadline time.Time, ok bool)Done() <-chan struct{}Err() errorValue(key any) any
}

这个 Context 依然是一个 interface,interface 的优点很明显,能简化结构,只需要写清楚使用协议就好。

3、Writer ResponseWriter

这个也是一个接口,它提供了一系列方法来写请求内容什么的:

type ResponseWriter interface {http.ResponseWriterhttp.Hijackerhttp.Flusherhttp.CloseNotifierStatus() intSize() intWriteString(string) (int, error)Written() boolWriteHeaderNow()Pusher() http.Pusher
}

比如:

func (w *responseWriter) Write(data []byte) (n int, err error) {w.WriteHeaderNow()n, err = w.ResponseWriter.Write(data)w.size += nreturn
}func (w *responseWriter) WriteString(s string) (n int, err error) {w.WriteHeaderNow()n, err = io.WriteString(w.ResponseWriter, s)w.size += nreturn
}func (w *responseWriter) Status() int {return w.status
}
...

4、Params Params

首先:

type Param struct {Key   stringValue string
}
...type Params []Param

可以看到 Params 是Param的 slice,params 则是字段 Params 的一个指针,方便参数传递,避免值拷贝。

它有一些方法:


func (ps Params) Get(name string) (string, bool) {for _, entry := range ps {if entry.Key == name {return entry.Value, true}}return "", false
}
func (ps Params) ByName(name string) (va string) {va, _ = ps.Get(name)return
}

通过 Get() 可以获取参数列表中的某个参数。

二、gin.Context 的功能

它提供的大量的方法。gin.Context 是 Gin 框架中的一个结构体类型,用于封装 HTTP 请求和响应的信息,以及提供一些方法,用于获取请求和响应的信息、设置响应头、设置响应状态码等操作。gin.Context 只在 Gin 框架内部使用,用于处理 HTTP 请求和响应。它与 HTTP 请求和响应一一对应,每个 HTTP 请求都会创建一个新的 gin.Context 对象,并在处理过程中传递。

BindWith(obj any, b binding.Binding) error
reset()
Copy() *gin.Context
HandlerName() string
HandlerNames() []string
Handler() gin.HandlerFunc
FullPath() string
Next()
IsAborted() bool
Abort()
AbortWithStatus(code int)
AbortWithStatusJSON(code int, jsonObj any)
AbortWithError(code int, err error) *gin.Error
Error(err error) *gin.Error
Set(key string, value any)
Get(key string) (value any, exists bool)
MustGet(key string) any
GetString(key string) (s string)
GetBool(key string) (b bool)
GetInt(key string) (i int)
GetInt64(key string) (i64 int64)
GetUint(key string) (ui uint)
GetUint64(key string) (ui64 uint64)
GetFloat64(key string) (f64 float64)
GetTime(key string) (t time.Time)
GetDuration(key string) (d time.Duration)
GetStringSlice(key string) (ss []string)
GetStringMap(key string) (sm map[string]any)
GetStringMapString(key string) (sms map[string]string)
GetStringMapStringSlice(key string) (smss map[string][]string)
Param(key string) string
AddParam(key string, value string)
Query(key string) (value string)
DefaultQuery(key string, defaultValue string) string
GetQuery(key string) (string, bool)
QueryArray(key string) (values []string)
initQueryCache()
GetQueryArray(key string) (values []string, ok bool)
QueryMap(key string) (dicts map[string]string)
GetQueryMap(key string) (map[string]string, bool)
PostForm(key string) (value string)
DefaultPostForm(key string, defaultValue string) string
GetPostForm(key string) (string, bool)
PostFormArray(key string) (values []string)
initFormCache()
GetPostFormArray(key string) (values []string, ok bool)
PostFormMap(key string) (dicts map[string]string)
GetPostFormMap(key string) (map[string]string, bool)
get(m map[string][]string, key string) (map[string]string, bool)
FormFile(name string) (*multipart.FileHeader, error)
MultipartForm() (*multipart.Form, error)
SaveUploadedFile(file *multipart.FileHeader, dst string) error
Bind(obj any) error
BindJSON(obj any) error
BindXML(obj any) error
BindQuery(obj any) error
BindYAML(obj any) error
BindTOML(obj any) error
BindHeader(obj any) error
BindUri(obj any) error
MustBindWith(obj any, b binding.Binding) error
ShouldBind(obj any) error
ShouldBindJSON(obj any) error
ShouldBindXML(obj any) error
ShouldBindQuery(obj any) error
ShouldBindYAML(obj any) error
ShouldBindTOML(obj any) error
ShouldBindHeader(obj any) error
ShouldBindUri(obj any) error
ShouldBindWith(obj any, b binding.Binding) error
ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error)
ClientIP() string
RemoteIP() string
ContentType() string
IsWebsocket() bool
requestHeader(key string) string
Status(code int)
Header(key string, value string)
GetHeader(key string) string
GetRawData() ([]byte, error)
SetSameSite(samesite http.SameSite)
SetCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool)
Cookie(name string) (string, error)
Render(code int, r render.Render)
HTML(code int, name string, obj any)
IndentedJSON(code int, obj any)
SecureJSON(code int, obj any)
JSONP(code int, obj any)
JSON(code int, obj any)
AsciiJSON(code int, obj any)
PureJSON(code int, obj any)
XML(code int, obj any)
YAML(code int, obj any)
TOML(code int, obj any)
ProtoBuf(code int, obj any)
String(code int, format string, values ...any)
Redirect(code int, location string)
Data(code int, contentType string, data []byte)
DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string)
File(filepath string)
FileFromFS(filepath string, fs http.FileSystem)
FileAttachment(filepath string, filename string)
SSEvent(name string, message any)
Stream(step func(w io.Writer) bool) bool
Negotiate(code int, config gin.Negotiate)
NegotiateFormat(offered ...string) string
SetAccepted(formats ...string)
hasRequestContext() bool
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key any) any

以上就是 gin.Context的大致结构和功能。

全文完,感谢阅读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/18209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】Docker consul 容器服务更新与发现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Docker consul 容器服务更新与发现 服务注册与发现consul 概述consul 部署consul服务器registrator服务器 consul-templateconsul 多节点 服务注册与发现 服务注册与发现是微…

什么是Java中的NIO(New IO)?

首先&#xff0c;NIO是什么&#xff1f;NIO全称是Java NIO&#xff08;New IO&#xff09;&#xff0c;它是一种新的I/O模型&#xff0c;相对于传统的I/O模型&#xff0c;NIO具有更高的性能和更低的延迟。在NIO中&#xff0c;我们使用通道&#xff08;Channels&#xff09;和缓…

Redis支持的数据持久化方法有哪些?它们之间有什么区别?

Redis支持两种数据持久化方法&#xff0c;分别是RDB&#xff08;快照&#xff09;和AOF&#xff08;日志&#xff09;&#xff1a; RDB&#xff08;Redis DataBase&#xff09;持久化&#xff1a;RDB是将内存中的数据定期保存到磁盘上的二进制文件。当某个条件满足时&#xff0…

matlab程序中文乱码

不同版本的matlab共存在GBK&#xff08;即&#xff0c;ANSI&#xff09;和UTF-8两种编码方式&#xff0c;因此可能会出现乱码问题。 第一步&#xff1a;在matlab的命令行窗口输入指令&#xff0c;查看当前编码方式 feature(locale) 第二步&#xff1a;用Notepad打开文件&…

chrome 插件开发

参考&#xff1a; https://www.cnblogs.com/amboke/p/16718855.html 设计和实现一个 Chrome 插件提升登录效率_若川的技术博客_51CTO博客 最新版 V3 chrome 插件开发~ demo 坑 - 掘金 官方文档&#xff1a;https://developer.chrome.com/docs/extensions/

【实战】 九、深入React 状态管理与Redux机制(二) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(十七)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…

C# 根据图片的EXIF自动调整图片方向

PropertyItems 代码 /// <summary>/// 根据图片exif调整方向/// </summary>/// <param name"img"></param>public void RotateImage(Bitmap img){var exif img.PropertyItems;byte orien 0;var item exif.Where(m > m.Id 274).ToArra…

林园价值交易策略

文章目录 选股策略林园6条炒股“心经” 选股策略 选股时可以考虑在低市盈率、高分红的绩优龙头股和确定性高的小盘股中选。 所选择的上市公司的财务指标需符合七大标准&#xff1a; 每股盈利不低于0.3元&#xff1b;净利润不少于7000万元&#xff1b;毛利率在20%以上&#x…

关于综合能源智慧管理系统的架构及模式规划的研究

安科瑞 华楠 摘 要&#xff1a;探讨了国内外能源互联网的研究发展&#xff0c;分析了有关综合智慧能源管理系统的定位&#xff0c;以及系统的主要特点&#xff0c;研究了综合智慧能源管理系统的构架以及模式规划。 关键词&#xff1a;综合能源&#xff1b;智慧管理系统&#…

前端开发:基于cypress的自动化实践

如何在vue中使用cypress如何运行cypress如何编写测试用例如何解决测试数据的问题遇到的元素定位的问题如何看待cypresscypress是否为最佳工具测试怎么办&#xff1f; 如何在vue中使用cypress vue提供了vue-cli 可以快速的创建vue项目。 vue create hello-world在选择安装项里…

SK5代理与IP代理:网络安全中的爬虫利器

一、什么是IP代理与SK5代理&#xff1f; IP代理&#xff1a; IP代理是一种允许用户通过代理服务器进行网络连接的技术。用户请求经由代理服务器中转&#xff0c;从而实现隐藏真实IP地址&#xff0c;保护用户隐私&#xff0c;并在一定程度上突破IP访问限制。常见的IP代理有HTTP…

【李宏毅机器学习·学习笔记】Deep Learning General Guidance

本节课可视为机器学习系列课程的一个前期攻略&#xff0c;这节课主要对Machine Learning 的框架进行了简单的介绍&#xff1b;并以training data上的loss大小为切入点&#xff0c;介绍了几种常见的在模型训练的过程中容易出现的情况。 课程视频&#xff1a; Youtube&#xff1…

【MTK平台】【wpa_supplicant】关于wpa_supplicant_8/src/p2p/p2p_invitation.c文件的介绍

本文主要介绍external/wpa_supplicant_8/src/p2p/p2p_invitation.c文件 这里主要介绍6个方法 1.p2p_invite //p2p邀请调用此方法 2.p2p_invite_send //对p2p_invite方法进行补充 3. p2p_process_invitation_resp 4.p2p_process_invitation_req 5.p2p_build_invitation_re…

Java并发系列之二:悲观锁机制

什么是锁 在并发环境下&#xff0c;会出现多个线程对同一个资源进行争抢的情况&#xff0c;假设A线程对资源正在进行修改&#xff0c;此时B线程此时又对资源进行了修改&#xff0c;这就可能会导致数据不一致的问题。为了解决这个问题&#xff0c;很多编程语言引入了锁机制&…

Python的正则表达式re模块的compile()方法有什么作用?

re模块是Python标准库中的正则表达式模块&#xff0c;它提供了对正则表达式的支持。re.compile()是re模块的一个方法&#xff0c;用于将正则表达式编译成可复用的正则对象。 正则表达式是用来匹配和处理文本模式的强大工具。当你需要在字符串中查找、替换或者提取符合特定模式…

前端学习--vue2--插槽

写在前面&#xff1a; 这个用法是在使用组件和创建组件中 文章目录 介绍简单使用多个插槽省写默认/后备内容作用域插槽常用实例Element-ui的el-table 废弃用法slot attributeslot-scope attribute 介绍 我们在定义一些组件的时候&#xff0c;由于组件内文字想要自定义&#…

python脚本记日志

1、使用RotatingFileHandler&#xff0c;可以实现日志按大小回滚&#xff08;设置&#xff0c;最多备份几个日志文件&#xff0c;每个日志文件最大值&#xff09;&#xff1a; import loggingfrom logging.handlers import RotatingFileHandler # 按文件大小回滚handlerdef ma…

ssh安全远程管理

目录 1、什么是ssh 2、ssh登陆 3、ssh文件传输 1、什么是ssh ssh是 Secure Shell 的缩写&#xff0c;是一个建立在应用层上的安全远程管理协议。ssh 是目前较为可靠的传输协议&#xff0c;专为远程登录会话和其他网络服务提供安全性。利用ssh 协议可以有效防止远程管理过程中…

蓝桥杯上岸每日N题 第五期(山)!!!

蓝桥杯上岸每日N题第五期 ❗️ ❗️ ❗️ 同步收录 &#x1f447; 蓝桥杯Java 省赛B组(初赛)填空题 大家好 我是寸铁&#x1f4aa; 冲刺蓝桥杯省一模板大全来啦 &#x1f525; 蓝桥杯4月8号就要开始了 &#x1f64f; 距离蓝桥杯省赛倒数第3天 ❗️ ❗️ ❗️ 还没背熟模…

机器学习笔记之优化算法(二)线搜索方法(方向角度)

机器学习笔记之优化算法——线搜索方法[方向角度] 引言回顾&#xff1a;线搜索方法从方向角度观察线搜索方法场景构建假设1&#xff1a;目标函数结果的单调性假设2&#xff1a;屏蔽步长 α k \alpha_k αk​对线搜索方法过程的影响假设3&#xff1a;限定向量 P k \mathcal P_k …