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

2023-10-13 15:20

本文主要是介绍字节赫兹 框架教程 一请求上下文之请求,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

请求上下文

请求上下文 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 == trueid, hasId := ctx.GetQuery("id") // id == "", hasId == falseage, 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 argss := 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 == trueage, hasAge := args.PeekExists("age") // age == "", hasAge == truelen := args.Len()                     // len == 4args.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.Writerreq := protocol.AcquireRequest()n, err := args.WriteTo(req.BodyWriter())// n == 31 err == nils := req.BodyBuffer().String()// s == "name=bar&age=&pets=dog&pets=cat"// change argsvar newArgs protocol.Argsargs.CopyTo(&newArgs)newArgs.Set("version", "v1")version := newArgs.Peek("version") //version == []byte("v1")newArgs.Del("age")hasAgeAfterDel := newArgs.Has("age") // hasAgeAfterDel == falsenewArgs.DelBytes([]byte("name"))hasNameAfterDel := newArgs.Has("name") // hasNameAfterDel == falsenewArgs.Add("name", "foo")newName := newArgs.Peek("name") //newName == []byte("foo")newArgs.Reset()empty := newArgs.String() // empty == ""// parse argsvar newArgs2 protocol.ArgsnewArgs2.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
Header
// RequestHeader
func (h *RequestHeader) Add(key, value string)
func (h *RequestHeader) Set(key, value string)
func (h *RequestHeader) Header() []byte
func (h *RequestHeader) String() string
func (h *RequestHeader) VisitAll(f func(key, value []byte))// RequestContext
func (ctx *RequestContext) IsGet() bool 
func (ctx *RequestContext) IsHead() bool
func (ctx *RequestContext) IsPost() bool
func (ctx *RequestContext) Method() []byte
func (ctx *RequestContext) ContentType() []byte
func (ctx *RequestContext) IfModifiedSince(lastModified time.Time) bool 
func (ctx *RequestContext) Cookie(key string) []byte
func (ctx *RequestContext) UserAgent() []byte
func (ctx *RequestContext) GetHeader(key string) []byte
Add

添加或设置键为 key 的 Header。

注意:Add 通常用于为同一个 Key 设置多个 Header,若要为同一个 Key 设置单个 Header 请使用 Set。当作用于 Content-Type, Content-Length, Connection, Cookie, Transfer-Encoding, Host, User-Agent 这些 Header 时,使用多个 Add 会覆盖掉旧值。

函数签名:

func (h *RequestHeader) Add(key, value string)

示例:

hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {ctx.Request.Header.Add("hertz1", "value1")ctx.Request.Header.Add("hertz1", "value2")ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))contentType1 := ctx.Request.Header.ContentType() // contentType1 == []byte("application/x-www-form-urlencoded")ctx.Request.Header.Add("Content-Type", "application/json; charset=utf-8")hertz1 := ctx.Request.Header.GetAll("hertz1") // hertz1 == []string{"value1", "value2"}contentType2 := ctx.Request.Header.ContentType() // contentType2 == []byte("application/json; charset=utf-8")})
Set

设置 Header 键值。

注意:Set 通常用于为同一个 Key 设置单个 Header,若要为同一个 Key 设置多个 Header 请使用 Add。

函数签名:

func (h *RequestHeader) Set(key, value string)

示例:

hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {ctx.Request.Header.Set("hertz1", "value1")ctx.Request.Header.Set("hertz1", "value2")ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))contentType1 := ctx.Request.Header.ContentType() // contentType1 == []byte("application/x-www-form-urlencoded")ctx.Request.Header.Set("Content-Type", "application/json; charset=utf-8")hertz1 := ctx.Request.Header.GetAll("hertz1")    // hertz1 == []string{"value2"}contentType2 := ctx.Request.Header.ContentType() // contentType2 == []byte("application/json; charset=utf-8")})
Header

获取 []byte 类型的完整的 Header。

函数签名:

func (h *RequestHeader) Header() []byte

示例:

 hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {ctx.Request.Header.Set("hertz1", "value1")ctx.Request.Header.Set("hertz1", "value2")ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))contentType1 := ctx.Request.Header.ContentType() // contentType1 == []byte("application/x-www-form-urlencoded")ctx.Request.Header.Set("Content-Type", "application/json; charset=utf-8")hertz1 := ctx.Request.Header.GetAll("hertz1")    // hertz1 == []string{"value2"}contentType2 := ctx.Request.Header.ContentType() // contentType2 == []byte("application/json; charset=utf-8")})
String

获取完整的 Header。

函数签名:

func (h *RequestHeader) String() string

示例:

hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {ctx.Request.Header.Set("hertz1", "value1")header := ctx.Request.Header.String()// header == "GET /example HTTP/1.1//User-Agent: PostmanRuntime-ApipostRuntime/1.1.0//Host: localhost:8888//Cache-Control: no-cache//Accept: */*//Accept-Encoding: gzip, deflate, br//Connection: keep-alive//Hertz1: value1"})
遍历 Header

遍历所有 Header 的键值并执行 f 函数。

函数签名:

func (h *RequestHeader) VisitAll(f func(key, value []byte))

示例:

hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {ctx.Request.Header.Add("Hertz1", "value1")ctx.Request.Header.Add("Hertz1", "value2")var hertzString []stringctx.Request.Header.VisitAll(func(key, value []byte) {if string(key) == "Hertz1" {hertzString = append(hertzString, string(value))}})// hertzString == []string{"value1", "value2"}})
ethod

获取请求方法的类型。

函数签名:

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

示例:

// POST http://example.com/user
h.Any("/user", func(c context.Context, ctx *app.RequestContext) {method := ctx.Method() // method == []byte("POST")
})
ContentType

获取请求头 Content-Type 的值。

函数签名:

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

示例:


// POST http://example.com/user
// Content-Type: application/json
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {contentType := ctx.ContentType() // contentType == []byte("application/json")
})
IfModifiedSince

判断时间是否超过请求头 If-Modified-Since 的值。

注意:如果请求头不包含 If-Modified-Since 也返回 true。

函数签名:

func (ctx *RequestContext) IfModifiedSince(lastModified time.Time) bool

示例:

// POST http://example.com/user
// If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {t2022, _ := time.Parse(time.RFC1123, "Wed, 21 Oct 2022 07:28:00 GMT")ifModifiedSince := ctx.IfModifiedSince(t2022) // ifModifiedSince == falset2024, _ := time.Parse(time.RFC1123, "Wed, 21 Oct 2024 07:28:00 GMT")ifModifiedSince = ctx.IfModifiedSince(t2024) // ifModifiedSince == true
})
Cookie

获取请求头 Cookie 中 key 的值。

函数签名:

func (ctx *RequestContext) Cookie(key string) []byte

示例:


// POST http://example.com/user
// Cookie: foo_cookie=choco; bar_cookie=strawberry
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {fCookie := ctx.Cookie("foo_cookie")     // fCookie == []byte("choco")bCookie := ctx.Cookie("bar_cookie")     // bCookie == []byte("strawberry")noneCookie := ctx.Cookie("none_cookie") // noneCookie == nil
})
UserAgent

获取请求头 User-Agent 的值。

函数签名:

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

示例:

// POST http://example.com/user
// User-Agent: Chrome/51.0.2704.103 Safari/537.36
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {ua := ctx.UserAgent() // ua == []byte("Chrome/51.0.2704.103 Safari/537.36")
})
GetHeader

获取请求头中 key 的值。

函数签名:

func (ctx *RequestContext) GetHeader(key string) []byte

示例:

// POST http://example.com/user
// Say-Hello: hello
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {customHeader := ctx.GetHeader("Say-Hello") // customHeader == []byte("hello")
})
Body
func (ctx *RequestContext) GetRawData() []byte
func (ctx *RequestContext) Body() ([]byte, error) 
func (ctx *RequestContext) RequestBodyStream() io.Reader
func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)
func (ctx *RequestContext) PostForm(key string) string
func (ctx *RequestContext) DefaultPostForm(key, defaultValue string) string 
func (ctx *RequestContext) GetPostForm(key string) (string, bool) 
func (ctx *RequestContext) PostArgs() *protocol.Args
func (ctx *RequestContext) FormValue(key string) []byte 
func (ctx *RequestContext) SetFormValueFunc(f FormValueFunc)
Body

获取请求的 body 数据,如果发生错误返回 error。

函数签名:

func (ctx *RequestContext) Body() ([]byte, error) 

示例:

// POST http://example.com/pet
// Content-Type: application/json
// {"pet":"cat"}
h.Post("/pet", func(c context.Context, ctx *app.RequestContext) {data, err := ctx.Body() // data == []byte("{\"pet\":\"cat\"}") , err == nil
})
RequestBodyStream

获取请求的 BodyStream。

函数签名:

func (ctx *RequestContext) RequestBodyStream() io.Reader

示例:


// POST http://example.com/user
// Content-Type: text/plain
// abcdefg
h := server.Default(server.WithStreamBody(true))
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {sr := ctx.RequestBodyStream()data, _ := io.ReadAll(sr) // data == []byte("abcdefg")
})
MultipartForm

获取 multipart.Form 对象,(详情请参考 multipart#Form)

注意:此函数既可以获取普通值也可以获取文件,此处给出了获取普通值的示例代码,获取文件的示例代码可参考 MultipartForm。

函数签名:

func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)

示例:

// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {form, err := ctx.MultipartForm()name := form.Value["name"][0] // name == "tom"
})
PostForm

按名称检索 multipart.Form.Value,返回给定 name 的第一个值。

注意:该函数支持从 application/x-www-form-urlencoded 和 multipart/form-data 这两种类型的 content-type 中获取 value 值,且不支持获取文件值。

函数签名:

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

示例:

// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {name := ctx.PostForm("name") // name == "tom"
})
DefaultPostForm

按名称检索 multipart.Form.Value,返回给定 name 的第一个值,如果不存在返回 defaultValue。

注意:该函数支持从 application/x-www-form-urlencoded 和 multipart/form-data 这两种类型的 content-type 中获取 value 值,且不支持获取文件值。

函数签名:

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

示例:

// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {name := ctx.PostForm("name", "jack") // name == "tom"age := ctx.PostForm("age", "10") // age == "10"
})
PostArgs

获取 application/x-www-form-urlencoded 参数对象。(详情请参考 Args 对象)

函数签名:

func (ctx *RequestContext) PostArgs() *protocol.Args

示例:

// POST http://example.com/user
// Content-Type: application/x-www-form-urlencoded
// name=tom&pet=cat&pet=dog
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {args := ctx.PostArgs()name := args.Peek("name") // name == "tom"var pets []stringargs.VisitAll(func(key, value []byte) {if string(key) == "pet" {pets = append(pets, string(value))}})// pets == []string{"cat", "dog"}
})
FormValue

按照以下顺序获取 key 的值。

从 QueryArgs 中获取值。
从 PostArgs 中获取值。
从 MultipartForm 中获取值。
函数签名:

func (ctx *RequestContext) FormValue(key string) []byte 

示例:

// POST http://example.com/user?name=tom
// Content-Type: application/x-www-form-urlencoded
// age=10
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {name := ctx.FormValue("name") // name == []byte("tom"), get by QueryArgsage := ctx.FormValue("age") // age == []byte("10"), get by PostArgs
})// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {name := ctx.FormValue("name") // name == []byte("tom"), get by MultipartForm
})
SetFormValueFunc

若 FormValue 函数提供的默认获取 key 的值的方式不满足需求,用户可以使用该函数自定义获取 key 的值的方式。

函数签名:


func (ctx *RequestContext) SetFormValueFunc(f FormValueFunc) 

示例:

// POST http://example.com/user?name=tom
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="age"
// 10
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {// only return multipart form valuectx.SetFormValueFunc(func(rc *app.RequestContext, s string) []byte {mf, err := rc.MultipartForm()if err == nil && mf.Value != nil {vv := mf.Value[s]if len(vv) > 0 {return []byte(vv[0])}}return nil})name := ctx.FormValue("name") // name == nilage := ctx.FormValue("age")   // age == []byte("10")
})
文件操作
func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)
func (ctx *RequestContext) FormFile(name string) (*multipart.FileHeader, error) 
func (ctx *RequestContext) SaveUploadedFile(file *multipart.FileHeader, dst string) error 
MultipartForm

获取 multipart.Form 对象。(详情请参考 multipart#Form)

注意:此函数既可以获取普通值也可以获取文件,此处给出了获取文件值的示例代码,获取普通值的示例代码可参考 MultipartForm。

函数签名:

func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)

示例:

// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="avatar"; filename="abc.jpg"
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {form, err := ctx.MultipartForm()avatarFile := form.File["avatar"][0] // avatarFile.Filename == "abc.jpg"
})
FormFile

按名称检索 multipart.Form.File,返回给定 name 的第一个 multipart.FileHeader。(详情请参考 multipart#FileHeader)

函数签名:

func (ctx *RequestContext) FormFile(name string) (*multipart.FileHeader, error)

示例:

// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="avatar"; filename="abc.jpg"
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {avatarFile, err := ctx.FormFile("avatar") // avatarFile.Filename == "abc.jpg", err == nil
})
SaveUploadedFile

保存 multipart 文件到磁盘。

函数签名:

func (ctx *RequestContext) SaveUploadedFile(file *multipart.FileHeader, dst string) error 

示例:

// POST http://example.com/user
// Content-Type: multipart/form-data; 
// Content-Disposition: form-data; name="avatar"; filename="abc.jpg"
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {avatarFile, err := ctx.FormFile("avatar") // avatarFile.Filename == "abc.jpg", err == nil// save filectx.SaveUploadedFile(avatarFile, avatarFile.Filename) // save file "abc.jpg"
})
Handler
func (ctx *RequestContext) Next(c context.Context) 
func (ctx *RequestContext) Handlers() HandlersChain 
func (ctx *RequestContext) Handler() HandlerFunc 
func (ctx *RequestContext) SetHandlers(hc HandlersChain) 
func (ctx *RequestContext) HandlerName() string 
func (ctx *RequestContext) GetIndex() int8 
func (ctx *RequestContext) Abort() 
func (ctx *RequestContext) IsAborted() bool
Next

执行下一个 handler,该函数通常用于中间件 handler 中。

函数签名:

func (ctx *RequestContext) Next(c context.Context)

示例:


h.POST("/user", func(c context.Context, ctx *app.RequestContext) {ctx.Next(c)v := ctx.GetString("version") // v == "v1"
}, func(c context.Context, ctx *app.RequestContext) {ctx.Set("version", "v1")
})
Handlers

获取 handlers chain。

函数签名:

func (ctx *RequestContext) Handlers() HandlersChain

示例:

middleware1 := func(c context.Context, ctx *app.RequestContext) {
}handler1 := func(c context.Context, ctx *app.RequestContext) {handlers := ctx.Handlers() // []Handler{middleware1, handler1}
}h.POST("/user", middleware1, handler1)
Handler

获取 handlers chain 的最后一个 handler,一般来说,最后一个 handler 是 main handler。

函数签名:

func (ctx *RequestContext) Handler() HandlerFunc

示例:

middleware1 := func(c context.Context, ctx *app.RequestContext) {lastHandler := ctx.Handler() // lastHandler == handler1
}handler1 := func(c context.Context, ctx *app.RequestContext) {
}h.POST("/user", middleware1, handler1)
SetHandlers

设置 handlers chain。

函数签名:

func (ctx *RequestContext) SetHandlers(hc HandlersChain)

示例:

handler1 := func(c context.Context, ctx *app.RequestContext) {ctx.Set("current", "handler1")
}handler := func(c context.Context, ctx *app.RequestContext) {hc := app.HandlersChain{ctx.Handlers()[0], handler1} // append handler1 into handlers chainctx.SetHandlers(hc)ctx.Next(c)current := ctx.GetString("current") // current == "handler1"ctx.String(consts.StatusOK, current)
}h.POST("/user", handler)
HandlerName

获取最后一个 handler 的函数名称。

函数签名:

func (ctx *RequestContext) HandlerName() string

示例:

package mainfunc main() {h := server.New()h.POST("/user", func(c context.Context, ctx *app.RequestContext) {hn := ctx.HandlerName() // hn == "main.main.func1"})
}
GetIndex

获取当前执行的 handler 在 handlers chain 中的 index。

函数签名:

func (ctx *RequestContext) GetIndex() int8

示例:


h.POST("/user", func(c context.Context, ctx *app.RequestContext) {index := ctx.GetIndex() // index == 0
}, func(c context.Context, ctx *app.RequestContext) {index := ctx.GetIndex() // index == 1
})
Abort

终止后续的 handler 执行。

函数签名:

func (ctx *RequestContext) Abort()

示例:

h.POST("/user", func(c context.Context, ctx *app.RequestContext) {ctx.Abort()
}, func(c context.Context, ctx *app.RequestContext) {// will not execute
})
IsAborted

获取后续的 handler 执行状态是否被终止。

函数签名:

func (ctx *RequestContext) IsAborted() bool

示例:

h.POST("/user", func(c context.Context, ctx *app.RequestContext) {ctx.Abort()isAborted := ctx.IsAborted() // isAborted == true
}, func(c context.Context, ctx *app.RequestContext) {// will not execute
})
参数绑定与校验
func (ctx *RequestContext) Bind(obj interface{}) error 
func (ctx *RequestContext) Validate(obj interface{}) error 
func (ctx *RequestContext) BindAndValidate(obj interface{}) error
获取 ClientIP
func (ctx *RequestContext) ClientIP() string 
func (ctx *RequestContext) SetClientIPFunc(f ClientIP) 
ClientIP

获取客户端 IP 的地址。

该函数的默认行为:若 X-Forwarded-For 或 X-Real-IP Header 中存在 ip,则从这两个 Header 中读 ip 并返回(优先级 X-Forwarded-For 大于 X-Real-IP),否则返回 remote address。

函数签名:

func (ctx *RequestContext) ClientIP() string 

示例:

// X-Forwarded-For: 20.20.20.20, 30.30.30.30
// X-Real-IP: 10.10.10.10
h.Use(func(c context.Context, ctx *app.RequestContext) {ip := ctx.ClientIP() // 20.20.20.20
})
SetClientIPFunc

若 ClientIP 函数提供的默认方式不满足需求,用户可以使用该函数自定义获取客户端 ip 的方式。

用户可以自己实现自定义函数,也可以通过设置 app.ClientIPOptions 实现。

注意:在设置 app.ClientIPOptions 时,TrustedCIDRs 需用户自定义(若不设置则固定返回 remote address),代表可信任的路由。若 remote address 位于可信任的路由范围内,则会选择从 RemoteIPHeaders 中获取 ip,否则返回 remote address。

函数签名:

func (ctx *RequestContext) SetClientIPFunc(f ClientIP) 

示例:


// POST http://example.com/user
// X-Forwarded-For: 30.30.30.30
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {// method 1customClientIPFunc := func(ctx *app.RequestContext) string {return "127.0.0.1"}ctx.SetClientIPFunc(customClientIPFunc)ip := ctx.ClientIP() // ip == "127.0.0.1"// method 2_, cidr, _ := net.ParseCIDR("127.0.0.1/32")opts := app.ClientIPOptions{RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},TrustedCIDRs:    []*net.IPNet{cidr},}ctx.SetClientIPFunc(app.ClientIPWithOption(opts))ip = ctx.ClientIP() // ip == "30.30.30.30"
})
并发安全
func (ctx *RequestContext) Copy() *RequestContext

Copy
拷贝 RequestContext 副本,提供协程安全的访问方式。

函数签名:

func (ctx *RequestContext) Copy() *RequestContext 
示例:h.POST("/user", func(c context.Context, ctx *app.RequestContext) {ctx1 := ctx.Copy()go func(context *app.RequestContext) {// safely}(ctx1)
})

这篇关于字节赫兹 框架教程 一请求上下文之请求的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/204141

相关文章

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

MySQL Workbench 安装教程(保姆级)

《MySQLWorkbench安装教程(保姆级)》MySQLWorkbench是一款强大的数据库设计和管理工具,本文主要介绍了MySQLWorkbench安装教程,文中通过图文介绍的非常详细,对大... 目录前言:详细步骤:一、检查安装的数据库版本二、在官网下载对应的mysql Workbench版本,要是

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp