gin 框架中的 gin.Context

这篇具有很好参考价值的文章主要介绍了gin 框架中的 gin.Context。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

〇、前言

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

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

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

一、gin.Context 结构

type Context struct {
	writermem responseWriter
	Request   *http.Request
	Writer    ResponseWriter

	Params   Params
	handlers HandlersChain
	index    int8
	fullPath string

	engine       *Engine
	params       *Params
	skippedNodes *[]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 responseWriter
	Request   *http.Request
	Writer    ResponseWriter
	Params    Params
	params    *Params

1、writermem responseWriter

type responseWriter struct {
	http.ResponseWriter
	size   int
	status 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           string
    URL              *url.URL
    Proto            string
    ProtoMajor       int
    ProtoMinor       int
    Header           Header
    Body             io.ReadCloser
    GetBody          func() (io.ReadCloser, error)
    ContentLength    int64
    TransferEncoding []string
    Close            bool
    Host             string
    Form             url.Values
    PostForm         url.Values
    MultipartForm    *multipart.Form
    Trailer          Header
    RemoteAddr       string
    RequestURI       string
    TLS              *tls.ConnectionState
    Cancel           <-chan struct{}
    Response         *Response
    ctx              context.Context
}

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

	Method           string
    URL              *url.URL
    Header           Header
    Host             string
    Form             url.Values
    PostForm         url.Values
    Response         *Response
    ctx              context.Context

看到这里有一个 *Response:

type Response struct {
    Status           string
    StatusCode       int
    Proto            string
    ProtoMajor       int
    ProtoMinor       int
    Header           Header
    Body             io.ReadCloser
    ContentLength    int64
    TransferEncoding []string
    Close            bool
    Uncompressed     bool
    Trailer          Header
    Request          *Request
    TLS              *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() error
    Value(key any) any
}

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

3、Writer ResponseWriter

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

type ResponseWriter interface {
    http.ResponseWriter
    http.Hijacker
    http.Flusher
    http.CloseNotifier
    Status() int
    Size() int
    WriteString(string) (int, error)
    Written() bool
    WriteHeaderNow()
    Pusher() http.Pusher
}

比如:

func (w *responseWriter) Write(data []byte) (n int, err error) {
	w.WriteHeaderNow()
	n, err = w.ResponseWriter.Write(data)
	w.size += n
	return
}

func (w *responseWriter) WriteString(s string) (n int, err error) {
	w.WriteHeaderNow()
	n, err = io.WriteString(w.ResponseWriter, s)
	w.size += n
	return
}

func (w *responseWriter) Status() int {
	return w.status
}
...

4、Params Params

首先:

type Param struct {
	Key   string
	Value 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的大致结构和功能。

全文完,感谢阅读。文章来源地址https://www.toymoban.com/news/detail-628592.html

到了这里,关于gin 框架中的 gin.Context的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [golang gin框架] 39.Gin商城项目-微服务实战之微服务架构

    单体架构在 中小企业内部 用的是非常多的,当 业务不复杂 , 团队规模不大 的时候,单体架构比微服务架构具有 更高的生产率 单体架构 当 业务比较复杂 , 并发量 比较大, 团队规模扩大的时候, 就需要引入微服务架构了,它比单体架构 具有 更高的生产率, 可以 节省成本 , 解

    2024年02月12日
    浏览(31)
  • [golang gin框架] 37.ElasticSearch 全文搜索引擎的使用

    ElasticSearch 是一个基于 Lucene 的 搜索服务器 ,它提供了一个 分布式多用户 能力的 全文搜索引擎 ,基于 RESTful web 接口,Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎,设计用于云计算中,能够达到 实时搜索 , 稳定 , 可靠

    2024年02月11日
    浏览(45)
  • 【Golang | Gin】net/http和Gin起web服务时的简单对比

    Gin 是一个用 Go (Golang) 编写的 Web 框架,详细介绍参考官网:https://gin-gonic.com/zh-cn/docs/introduction/ 开始学习Gin之前,我们先首先回顾下使用net/http起一个简单的helloworld服务 注: 1、 http.HandleFunc : 使用一个默认的 DefaultServeMux 来注册路由信息。 / 是一个 pattern , greet 是一个 ha

    2024年02月08日
    浏览(38)
  • [golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务

    本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解 在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能 编辑 这个验证码功能封装代码captcha.go如下: 把这个

    2024年02月16日
    浏览(30)
  • [golang gin框架] 38.Gin操作Elasticsearch创建索引、修改映射、数据CURD以及数据分页

    常见的 Golang 操作 ElasticSearch 的插件主要有下面两个: 第三方插件: github.com/olivere/elastic 官网插件 github.com/elastic/go-elasticsearch 其中 elastic 比 go-elasticsearch 文档更全面一些,start 量也更多一些,本节讲解 elastic 使用第三方库 https://github.com/olivere/elastic 来连接 ES 并进行操作 注意

    2024年02月09日
    浏览(48)
  • Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

    欢迎关注「 全栈工程师修炼指南 」公众号 点击 👇  下方卡片  即可关注我哟! 设为 「 星标⭐ 」 每天带你  基础入门  到  进阶实践  再到  放弃学习 ! 专注  企业运维实践、网络安全、系统运维、应用开发、物联网实战、全栈文章  等知识分享 “    花开堪折直须折

    2024年02月08日
    浏览(33)
  • [golang gin框架] 45.Gin商城项目-微服务实战之后台Rbac微服务之角色权限关联

    角色和权限的关联关系在前面文章中有讲解,见[golang gin框架] 14.Gin 商城项目-RBAC管理之角色和权限关联,角色授权,在这里通过微服务来实现 角色对权限的授权 操作,这里要实现的有两个功能,一个是进入授权,另一个是,授权提交操作,页面如下:  这里需要在proto/rbacRole.proto中增加

    2024年02月14日
    浏览(42)
  • [golang gin框架] 26.Gin 商城项目-前台自定义商品列表模板, 商品详情数据渲染,Markdown语法使用

    当在首页分类点击进入分类商品列表页面时,可以根据后台分类中的分类模板跳转到对应的模板商品列表页面 (1).商品控制器方法Category()完善 修改controllers/frontend/productController.go中的方法Category(), 判断分类模板,如果后台没有设置,则使用默认模板 (2).模板页面案例 先来回顾一

    2024年02月01日
    浏览(43)
  • [golang gin框架] 42.Gin商城项目-微服务实战之后台Rbac微服务角色增删改查微服务

    上一节讲解了后台Rbac微服务用户登录功能以及Gorm数据库配置单独抽离,Consul配置单独抽离,这一节讲解 后台Rbac微服务 角色 增删改查微服务 功能,Rbac微服务角色增删改查微服务和 后 台Rbac用户登录微服务 是属于 同一个Rbac微服务 的 不同子微服务功能 ,为了区分不同子微

    2024年02月15日
    浏览(31)
  • [golang gin框架] 44.Gin商城项目-微服务实战之后台Rbac微服务之权限的增删改查微服务

    上一节讲解了[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联,这里讲解权限管理Rbac微服务权限的增删改查微服务 要实现权限的增删改查,就需要创建对应的模型,故在server/rbac/models下创建Access.go模型文件,参考[golang gin框架]

    2024年02月14日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包