最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Gin框架中bind的使用

 更新時(shí)間:2021年12月10日 15:34:14   作者:xiaojinran  
Gin框架中有bind函數(shù),可以非常方便的將url的查詢參數(shù)query?parameter、http的Header,body中提交上來的數(shù)據(jù)格式,本文就詳細(xì)的介紹Gin框架中bind的使用,感興趣的可以了解一下

概述

Gin框架中,有bind函數(shù)可以非常方便的將url的查詢參數(shù)query parameter、http的Header,body中提交上來的數(shù)據(jù)格式,如form,json,xml等,綁定到go中的結(jié)構(gòu)體中去,這期間Binding做了啥事情,這么多個(gè)Bindding函數(shù),我們?cè)撊绾芜x擇,一起通過源碼來解開其中神秘的面紗吧。

Binding接口

type Binding interface {
   Name() string
   Bind(*http.Request, interface{}) error
}

Binding是一個(gè)接口,在源碼中,有10個(gè)實(shí)現(xiàn)了Binding的結(jié)構(gòu)體,以及3個(gè)接口

在這里插入圖片描述?

context.Bind

// Bind checks the Content-Type to select a binding engine automatically,
// Depending the "Content-Type" header different bindings are used:
//     "application/json" --> JSON binding
//     "application/xml"  --> XML binding
// otherwise --> returns an error.
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It decodes the json payload into the struct specified as a pointer.
// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid.
func (c *Context) Bind(obj interface{}) error {
	b := binding.Default(c.Request.Method, c.ContentType())
	return c.MustBindWith(obj, b)
}

cnotext.MustBindWith

// MustBindWith binds the passed struct pointer using the specified binding engine.
// It will abort the request with HTTP 400 if any error occurs.
// See the binding package.
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
   if err := c.ShouldBindWith(obj, b); err != nil {
      c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
      return err
   }
   return nil
}

從注解和源碼可以看出,MustBindWith最終也是調(diào)用了SouldBindWith,并且對(duì)ShouldBindWith的結(jié)果進(jìn)行了判斷,如果有錯(cuò)誤,則以http 400的狀態(tài)碼進(jìn)行退出。

ShouldBindWith

// ShouldBindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
   return b.Bind(c.Request, obj)
}

這個(gè)方法是所有其他綁定方法的一個(gè)基礎(chǔ),基本上所有的綁定方法都需要用到這個(gè)方法來對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行一個(gè)綁定

以上為主要的bingding的過程,其他派生出來的如BindJSON、ShouldBindJSON等,為具體的數(shù)據(jù)類型的快捷方式而已,只是幫我們把具體的bingding的數(shù)據(jù)類型提前給封裝了起來而已,如Json格式的bingding函數(shù)

context.BindJSON

// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
func (c *Context) BindJSON(obj interface{}) error {
   return c.MustBindWith(obj, binding.JSON)
}

context.BindJSON從源碼上分析,可以看到,僅僅比Bind方法少了一句

b := binding.Default(c.Request.Method, c.ContentType())

這一句是為了判斷當(dāng)前的請(qǐng)求方法和contentType,來給context.MustBindWith傳的一個(gè)具體的bingding類型。

Json的實(shí)現(xiàn)的Binding接口如下

func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
   if req == nil || req.Body == nil {
      return fmt.Errorf("invalid request")
   }
   return decodeJSON(req.Body, obj)
}

jsonBinding結(jié)構(gòu)體實(shí)現(xiàn)了Binding接口的Bind方法,將請(qǐng)求過來的Body數(shù)據(jù)進(jìn)行解碼,綁定到obj里面去

context.ShouldBindJSON

// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON).
func (c *Context) ShouldBindJSON(obj interface{}) error {
   return c.ShouldBindWith(obj, binding.JSON)
}

從源碼的注解來看,ShouldBindJSON其實(shí)就是ShouldBindWith(obj, binding.JSON)的快捷方式,簡單來說,就是在ShouldBindWith(obj, binding.JSON)上面固定了參數(shù),當(dāng)我們明確規(guī)定,body提交的參數(shù)內(nèi)容為json時(shí),簡化了我們的調(diào)用和增強(qiáng)了代碼的可讀性。

context.ShouldBindUri()

// ShouldBindUri binds the passed struct pointer using the specified binding engine.
func (c *Context) ShouldBindUri(obj interface{}) error {
   m := make(map[string][]string)
   for _, v := range c.Params {
      m[v.Key] = []string{v.Value}
   }
   return binding.Uri.BindUri(m, obj)
}

從url綁定采用的方法跟header和body的方式不一樣,不需要傳入一個(gè)實(shí)現(xiàn)Binding接口的結(jié)構(gòu)體類型

context.ShouldBindUri()

// BindUri binds the passed struct pointer using binding.Uri.
// It will abort the request with HTTP 400 if any error occurs.
func (c *Context) BindUri(obj interface{}) error {
   if err := c.ShouldBindUri(obj); err != nil {
      c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
      return err
   }
   return nil
}

BindUri也是對(duì)ShouldBindUri的一個(gè)封裝,多了一個(gè)對(duì)ShouldBindUri結(jié)果的一個(gè)判斷 代碼實(shí)例

代碼如下

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)
type queryHeader struct {
	Myheader string `header:"myheader"`
	Mydemo string `header:"mydemo"`
}

type queryBody struct {
	Name string `json:"name"`
	Age int `json:"age"`
	Sex int `json:"sex"`
}

type queryParameter struct {
	Year int `form:"year"`
	Month int `form:"month"`
}

type queryUri struct {
	Id int `uri:"id"`
	Name string `uri:"name"`
}

func bindUri(context *gin.Context){
	var q queryUri
	err:= context.ShouldBindUri(&q)
	if err != nil {
		context.JSON(http.StatusBadRequest,gin.H{
			"result":err.Error(),
		})
		return
	}
	context.JSON(http.StatusOK,gin.H{
		"result":"綁定成功",
		"uri": q,
	})
}

func bindQuery(context *gin.Context){
	var q queryParameter
	err:= context.ShouldBindQuery(&q)
	if err != nil {
		context.JSON(http.StatusBadRequest,gin.H{
			"result":err.Error(),
		})
		return
	}
	context.JSON(http.StatusOK,gin.H{
		"result":"綁定成功",
		"query": q,
	})
}

func bindBody(context *gin.Context){
	var q queryBody
	err:= context.ShouldBindJSON(&q)
	if err != nil {
		context.JSON(http.StatusBadRequest,gin.H{
			"result":err.Error(),
		})
		return
	}
	context.JSON(http.StatusOK,gin.H{
		"result":"綁定成功",
		"body": q,
	})
}

func bindhead(context *gin.Context){
	var q queryHeader
	err := context.ShouldBindHeader(&q)
	if err != nil {
		context.JSON(http.StatusBadRequest,gin.H{
			"result":err.Error(),
		})
		return
	}
	context.JSON(http.StatusOK,gin.H{
		"result":"綁定成功",
		"header": q,
	})
}

func main(){
	srv := gin.Default()
	srv.GET("/binding/header",bindhead)
	srv.GET("/binding/body",bindBody)
	srv.GET("/binding/query",bindQuery)
	srv.GET("/binding/:id/:name",bindUri)
	srv.Run(":9999")
}

運(yùn)行結(jié)果

綁定Header數(shù)據(jù)

在這里插入圖片描述

綁定QueryParameter數(shù)據(jù)

在這里插入圖片描述

綁定Body Json數(shù)據(jù)

在這里插入圖片描述

綁定Uri數(shù)據(jù)

在這里插入圖片描述

總結(jié)

  • 使用gin框架中的bind方法,可以很容易對(duì)http請(qǐng)求過來的數(shù)據(jù)傳遞到我們的結(jié)構(gòu)體指針去,方便我們代碼編程。
  • 當(dāng)參數(shù)比較簡單,不需要結(jié)構(gòu)體來進(jìn)行封裝時(shí)候,此時(shí)還需采用context的其他方法來獲取對(duì)應(yīng)的值
  • gin在bind的時(shí)候,未對(duì)結(jié)構(gòu)體的數(shù)據(jù)進(jìn)行有效性檢查,如果對(duì)數(shù)據(jù)有強(qiáng)要求時(shí),需要自己對(duì)結(jié)構(gòu)體的數(shù)據(jù)內(nèi)容進(jìn)行判斷
  • 建議在實(shí)踐過程中,使用shouldBind<xxx>函數(shù)

到此這篇關(guān)于淺談Gin框架中bind的使用的文章就介紹到這了,更多相關(guān)Gin框架中bind內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang Gorm實(shí)現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢

    Golang Gorm實(shí)現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢

    GORM 是一個(gè)流行的開源 ORM (Object-Relational Mapping) 庫,專為 Go 語言設(shè)計(jì),它簡化了與 SQL 數(shù)據(jù)庫的交互,GORM 封裝了數(shù)據(jù)庫操作,使得開發(fā)者能夠通過簡單的鏈?zhǔn)秸{(diào)用來執(zhí)行 CRUD,本文給大家介紹了Golang Gorm實(shí)現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢,需要的朋友可以參考下
    2024-11-11
  • golang字符串切片去重的幾種算法

    golang字符串切片去重的幾種算法

    這篇文章主要介紹了golang字符串切片去重的幾種算法的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • go并發(fā)利器sync.Once使用示例詳解

    go并發(fā)利器sync.Once使用示例詳解

    這篇文章主要為大家介紹了go并發(fā)利器sync.Once使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • go換國內(nèi)源的方法步驟

    go換國內(nèi)源的方法步驟

    在中國境內(nèi),由于網(wǎng)絡(luò)原因,直接下載Go語言的包可能會(huì)遇到速度慢或下載失敗的問題,可以使用國內(nèi)的Go模塊代理來加速下載速度,本文就來介紹一下go換國內(nèi)源的方法步驟,感興趣的可以了解一下
    2024-09-09
  • Go語言中兩個(gè)比較流行的緩存庫使用示例

    Go語言中兩個(gè)比較流行的緩存庫使用示例

    緩存是計(jì)算機(jī)科學(xué)中的一個(gè)重要概念,設(shè)想某個(gè)組件需要訪問外部資源,它向外部源請(qǐng)求資源,接收并使用資源,這些步驟都需要花費(fèi)時(shí)間,下面這篇文章主要給大家介紹了關(guān)于Go語言中兩個(gè)比較流行的緩存庫使用的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • Go語言實(shí)現(xiàn)的web爬蟲實(shí)例

    Go語言實(shí)現(xiàn)的web爬蟲實(shí)例

    這篇文章主要介紹了Go語言實(shí)現(xiàn)的web爬蟲,實(shí)例分析了web爬蟲的原理與Go語言的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go語言實(shí)現(xiàn)二分查找方法示例

    Go語言實(shí)現(xiàn)二分查找方法示例

    這篇文章主要為大家介紹了Go語言實(shí)現(xiàn)二分查找方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 用Go獲取短信驗(yàn)證碼的示例代碼

    用Go獲取短信驗(yàn)證碼的示例代碼

    要用Go獲取短信驗(yàn)證碼,通常需要連接到一個(gè)短信服務(wù)提供商的API,并通過該API發(fā)送請(qǐng)求來獲取驗(yàn)證碼,由于不同的短信服務(wù)提供商可能具有不同的API和授權(quán)方式,我將以一個(gè)簡單的示例介紹如何使用Go語言來獲取短信驗(yàn)證碼,需要的朋友可以參考下
    2023-07-07
  • Go string轉(zhuǎn)int,int64,int32及注意事項(xiàng)說明

    Go string轉(zhuǎn)int,int64,int32及注意事項(xiàng)說明

    這篇文章主要介紹了Go string轉(zhuǎn)int,int64,int32及注意事項(xiàng)說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段

    golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段

    這篇文章主要介紹了golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評(píng)論

平舆县| 大安市| 湘阴县| 广东省| 霸州市| 嘉祥县| 凤城市| 乐平市| 封开县| 玛曲县| 海城市| 柘城县| 台东县| 邹城市| 察隅县| 都兰县| 阜阳市| 内乡县| 恩平市| 德兴市| 合江县| 东阿县| 九龙坡区| 应用必备| 汤原县| 吴桥县| 云龙县| 武鸣县| 瑞金市| 西峡县| 三明市| 泊头市| 洱源县| 资兴市| 耒阳市| 鹤岗市| 临夏县| 自治县| 灵宝市| 安远县| 大英县|