字节赫兹 框架教程 一请求上下文之请求(一)

简介: 字节赫兹 框架教程 一请求上下文之请求

请求上下文

请求上下文 RequestContext 是用于保存 HTTP 请求和设置 HTTP 响应的上下文,它提供了许多方便的 API 接口帮助用户开发。

Hertz 在 HandlerFunc 设计上,同时提供了一个标准 context.Context 和一个 RequestContext 作为函数的入参。 handler/middleware 函数签名为:

type HandlerFunc func(c context.Context, ctx *RequestContext)

context.Context 与 RequestContext 都有存储值的能力,具体选择使用哪一个上下文有个简单依据:所储存值的生命周期和所选择的上下文要匹配。

ctx 主要用来存储请求级别的变量,请求结束就回收了,特点是查询效率高(底层是 map),协程不安全,且未实现 context.Context 接口。

c 作为上下文在中间件 /handler 之间传递,协程安全。所有需要 context.Context 接口作为入参的地方,直接传递 c 即可。

请求

URI
func (ctx *RequestContext) Host() []byte 
func (ctx *RequestContext) FullPath() string 
func (ctx *RequestContext) SetFullPath(p string)
func (ctx *RequestContext) Path() []byte 
func (ctx *RequestContext) Param(key string) string
func (ctx *RequestContext) Query(key string) string
func (ctx *RequestContext) DefaultQuery(key, defaultValue string) string
func (ctx *RequestContext) GetQuery(key string) (string, bool) 
func (ctx *RequestContext) QueryArgs() *protocol.Args
func (ctx *RequestContext) URI() *protocol.URI 
Host

获取请求的主机地址。

函数签名:

func (ctx *RequestContext) Host() []byte 

示例:

// GET http://example.com
h.GET("/", func(c context.Context, ctx *app.RequestContext) {
    host := ctx.Host() // host == []byte("example.com")
})
FullPath

获取匹配的路由完整路径,对于未匹配的路由返回空字符串。

函数签名:

func (ctx *RequestContext) FullPath() string 

示例:

h := server.Default(server.WithHandleMethodNotAllowed(true))
// GET http://example.com/user/bar
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
    fpath := ctx.FullPath() // fpath == "/user/:name"
})
// GET http://example.com/bar
h.NoRoute(func(c context.Context, ctx *app.RequestContext) {
    fpath := ctx.FullPath() // fpath == ""
})
// POST http://example.com/user/bar
h.NoMethod(func(c context.Context, ctx *app.RequestContext) {
    fpath := ctx.FullPath() // fpath == ""
})
SetFullPath

设置 FullPath 的值。

注意:FullPath 由路由查找时分配,通常你不需要使用 SetFullPath 去覆盖它。

函数签名:

func (ctx *RequestContext) SetFullPath(p string)

示例:

h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
    ctx.SetFullPath("/v1/user/:name")
    fpath := ctx.FullPath() // fpath == "/v1/user/:name"
})
Path

获取请求的路径。

注意:出现参数路由时 Path 给出命名参数匹配后的路径,而 FullPath 给出原始路径。

函数签名:

func (ctx *RequestContext) Path() []byte 

示例:

// GET http://example.com/user/bar
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
    path := ctx.Path() // path == []byte("/user/bar")
})
Param

获取路由参数的值。

函数签名:

func (ctx *RequestContext) Param(key string) string 

示例:

// GET http://example.com/user/bar
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
    name := ctx.Param("name") // name == "bar"
    id := ctx.Param("id") // id == ""
})
Query

获取路由 Query String 参数中指定属性的值,如果没有返回空字符串。

函数签名:

func (ctx *RequestContext) Query(key string) string

示例:

// GET http://example.com/user?name=bar
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
    name := ctx.Query("name") // name == "bar"
    id := ctx.Query("id") // id == ""
})
DefaultQuery

获取路由 Query String 参数中指定属性的值,如果没有返回设置的默认值。

函数签名:

func (ctx *RequestContext) DefaultQuery(key, defaultValue string) string

示例:

// GET http://example.com/user?name=bar&&age=
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
    name := ctx.DefaultQuery("name", "tom") // name == "bar"
    id := ctx.DefaultQuery("id", "123") // id == "123"
    age := ctx.DefaultQuery("age", "45") // age == ""
})
GetQuery

获取路由 Query String 参数中指定属性的值以及属性是否存在。

函数签名:

func (ctx *RequestContext) GetQuery(key string) (string, bool)

示例:

// GET http://example.com/user?name=bar&&age=
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
    name, hasName := ctx.GetQuery("name") // name == "bar", hasName == true
    id, hasId := ctx.GetQuery("id") // id == "", hasId == false
    age, hasAge := ctx.GetQuery("age") // age == "", hasAge == true
})
QueryArgs

获取路由 Query String 参数对象。

函数签名:

func (ctx *RequestContext) QueryArgs() *protocol.Args
Args 对象

Args 对象提供了以下方法获取/设置 Query String 参数。

函数签名 说明
func (a *Args) Set(key, value string) 设置 Args 对象 key 的值
func (a *Args) Reset() 重置 Args 对象
func (a *Args) CopyTo(dst *Args) 将 Args 对象拷贝到 dst
func (a *Args) Del(key string) 删除 Args 对象 key 的键值对
func (a *Args) DelBytes(key []byte) 删除 Args 对象字节数组类型 key 的键值对
func (a *Args) Has(key string) bool 获取 Args 对象是否存在 key 的键值对
func (a *Args) String() string 将 Args 对象转换为字符串类型的 Query String
func (a *Args) QueryString() []byte 将 Args 对象转换为字节数组类型的 Query String
func (a *Args) ParseBytes(b []byte) 解析字节数组并将键值对存入 Args 对象
func (a *Args) Peek(key string) []byte 获取 Args 对象 key 的值
func (a *Args) PeekExists(key string) (string, bool) 获取 Args 对象 key 的值以及是否存在
func (a *Args) Len() int 获取 Args 对象键值对数量
func (a *Args) AppendBytes(dst []byte) []byte 将 Args 对象 Query String 附加到 dst 中并返回
func (a *Args) VisitAll(f func(key, value []byte)) 遍历 Args 对象所有的键值对
func (a *Args) WriteTo(w io.Writer) (int64, error) 将 Args 对象 Query String 写入 io.Writer 中
func (a *Args) Add(key, value string) 添加 Args 对象键为 key 的值
示例:
// GET http://example.com/user?name=bar&&age=&&pets=dog&&pets=cat
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
    args := ctx.QueryArgs()
    // get information from args
    s := args.String()                    // s == "name=bar&age=&pets=dog&pets=cat"
    qs := args.QueryString()              // qs == []byte("name=bar&age=&pets=dog&pets=cat")
    cpqs := args.AppendBytes([]byte(nil)) // cpqs == []byte("name=bar&age=&pets=dog&pets=cat")
    name := args.Peek("name")             // name == []byte("bar")
    hasName := args.Has("name")           // hasName == true
    age, hasAge := args.PeekExists("age") // age == "", hasAge == true
    len := args.Len()                     // len == 4
    args.VisitAll(func(key, value []byte) {
        // 1. key == []byte("name"), value == []byte("bar")
        // 2. key == []byte("age"), value == nil
        // 3. key == []byte("pets"), value == []byte("dog")
        // 4. key == []byte("pets"), value == []byte("cat")
    })
    // send information to io.Writer
    req := protocol.AcquireRequest()
  n, err := args.WriteTo(req.BodyWriter())
    // n == 31 err == nil
  s := req.BodyBuffer().String()
    // s == "name=bar&age=&pets=dog&pets=cat"
    // change args
    var newArgs protocol.Args
    args.CopyTo(&newArgs)
    newArgs.Set("version", "v1")
    version := newArgs.Peek("version") //version == []byte("v1")
    newArgs.Del("age")
    hasAgeAfterDel := newArgs.Has("age") // hasAgeAfterDel == false
    newArgs.DelBytes([]byte("name"))
    hasNameAfterDel := newArgs.Has("name") // hasNameAfterDel == false
    newArgs.Add("name", "foo")
    newName := newArgs.Peek("name") //newName == []byte("foo")
    newArgs.Reset()
    empty := newArgs.String() // empty == ""
    // parse args
    var newArgs2 protocol.Args
    newArgs2.ParseBytes([]byte("name=bar&age=20"))
    nqs2 := newArgs2.String() // nqs2 == "name=bar&age=20"
})
URI

返回请求的 URI 对象。

函数签名:

func (ctx *RequestContext) URI() *protocol.URI

URI 对象提供了以下方法获取/设置 URI。

函数签名 说明
func (u *URI) CopyTo(dst *URI) 拷贝 URI 对象的副本到 dst
func (u *URI) QueryArgs() *Args 获取 Args 对象
func (u *URI) Hash() []byte 获取 Hash 值,比如 http://example.com/user?baz=123#qwe 的 Hash 是 qwe
func (u *URI) SetHash(hash string) 设置 Hash
func (u *URI) SetHashBytes(hash []byte) 设置 []byte 类型 Hash
func (u *URI) Username() []byte 获取 Username
func (u *URI) SetUsername(username string) 设置 Username
func (u *URI) SetUsernameBytes(username []byte) 设置 []byte 类型 Username
func (u *URI) Password() []byte 获取 Password
func (u *URI) SetPassword(password string) 设置 Password
func (u *URI) SetPasswordBytes(password []byte) 设置 []byte 类型 Password
func (u *URI) QueryString() []byte 获取 Query String,比如 http://example.com/user?baz=123 的 Query String 是 baz=123
func (u *URI) SetQueryString(queryString string) 设置 Query String
func (u *URI) SetQueryStringBytes(queryString []byte) 设置 []byte 类型的 Query String
func (u *URI) Path() []byte 获取 Path,比如 http://example.com/user/he%20rtz 的 Path 是 /user/he rtz
func (u *URI) PathOriginal() []byte 获取未转义的 Path,比如 http://example.com/user/he%20rtz 的 Path 是 /user/he%20rtz
func (u *URI) SetPath(path string) 设置 Path
func (u *URI) SetPathBytes(path []byte) 设置 []byte 类型 Path
func (u *URI) String() string 获取完整 URI 比如 http://example.com/user?baz=123 的完整 URI 是 http://example.com/user?baz=123
func (u *URI) FullURI() []byte 获取 []byte 类型的完整 URI
func (u *URI) Scheme() []byte 获取协议,如 http
func (u *URI) SetScheme(scheme string) 设置协议
func (u *URI) SetSchemeBytes(scheme []byte) 设置 []byte 类型的协议
func (u *URI) Host() []byte 获取 Host,比如 http://example.com/user 的 Host 是 example.com
func (u *URI) SetHost(host string) 设置 Host
func (u *URI) SetHostBytes(host []byte) 设置 []byte 类型 Host
func (u *URI) LastPathSegment() []byte 获取 Path 的最后一部分,比如 Path /foo/bar/baz.html 的最后一部分是 baz.html
func (u *URI) Update(newURI string) 更新 URI
func (u *URI) UpdateBytes(newURI []byte) 更新 []byte 类型的 URI
func (u *URI) Parse(host, uri []byte) 初始化 URI
func (u *URI) AppendBytes(dst []byte) []byte 将完整的 URI 赋值到 dst 中并返回 dst
func (u *URI) RequestURI() []byte 获取 RequestURI,比如 http://example.com/user?baz=123 的 RequestURI 是 /user?baz=123
func (u *URI) Reset() 重置 URI


字节赫兹 框架教程 一请求上下文之请求(二)https://developer.aliyun.com/article/1391803

相关文章
|
6月前
|
安全 中间件
字节赫兹 框架教程 一请求上下文之请求(三)
字节赫兹 框架教程 一请求上下文之请求
76 0
|
监控 前端开发 网络协议
GB/T 28181-2016多响应消息传输探究
我们在实现Android平台GB28181设备接入模块的时候,有遇到发送多条记录的情况,本文主要探讨下GB28181多响应传输。
|
12月前
|
资源调度 流计算
Flink 指标参数源码解读(读取数量、发送数量、发送字节数、接收字节数等)(下)
Flink 指标参数源码解读(读取数量、发送数量、发送字节数、接收字节数等)(下)
149 1
|
22天前
|
存储 前端开发 NoSQL
拿下奇怪的前端报错(四):1比特丢失导致的音视频播放时长无限增长-浅析http分片传输核心和一个坑点
在一个使用MongoDB GridFS存储文件的项目中,音频和视频文件在大部分设备上播放时长显示为无限,而单独播放则正常。经调查发现,问题源于HTTP Range请求的处理不当,导致最后一个字节未被正确返回。通过调整请求参数,使JavaScript/MongoDB的操作范围与HTTP Range一致,最终解决了这一问题。此案例强调了对HTTP协议深入理解及跨系统集成时注意细节的重要性。
|
2月前
|
Python
8. 如何解决 Tornado 检测到了有事件(events)被发送到一个已经关闭的流(stream)。在 Tornado 中,一个流代表一个请求或响应的数据流。这个警告可能意味着在请求处理的过程中,
8. 如何解决 Tornado 检测到了有事件(events)被发送到一个已经关闭的流(stream)。在 Tornado 中,一个流代表一个请求或响应的数据流。这个警告可能意味着在请求处理的过程中,
|
6月前
|
数据采集 搜索推荐 API
python爬虫如何处理请求频率限制?
【2月更文挑战第21天】【2月更文挑战第64篇】python爬虫如何处理请求频率限制?
524 3
|
12月前
|
监控 流计算
Flink 指标参数源码解读(读取数量、发送数量、发送字节数、接收字节数等)(上)
Flink 指标参数源码解读(读取数量、发送数量、发送字节数、接收字节数等)(上)
86 1
|
6月前
字节赫兹 框架教程 一请求上下文之请求(二)
字节赫兹 框架教程 一请求上下文之请求
58 0
|
存储 算法
【实测】大白话讲requests发送请求的不同参数类型(上)
【实测】大白话讲requests发送请求的不同参数类型(上)
|
XML JSON 前端开发
【实测】大白话讲requests发送请求的不同参数类型(下)
【实测】大白话讲requests发送请求的不同参数类型(下)