欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang?Gin解析JSON請(qǐng)求數(shù)據(jù)避免出現(xiàn)EOF錯(cuò)誤

 更新時(shí)間:2022年04月29日 08:33:27   作者:EvaCcino  
這篇文章主要為大家介紹了Golang?Gin?優(yōu)雅地解析JSON請(qǐng)求數(shù)據(jù),避免ShouldBindBodyWith出現(xiàn)EOF錯(cuò)誤的源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

JSON是前后端交互的重要數(shù)據(jù)類型之一,使用Gin Web框架可以很方便地將HTTP請(qǐng)求報(bào)文中JSON格式的Body數(shù)據(jù)解析到結(jié)構(gòu)體Struct或字典Map數(shù)據(jù)結(jié)構(gòu)中。

環(huán)境

go version go1.14.3 windows/amd64
github.com/gin-gonic/gin v1.6.3

1. 結(jié)論

參考 Fix #216: Enable to call binding multiple times in some formats #1341

使用場(chǎng)景函數(shù)
單次綁定ShouldBindJSON > BindJSON
多次綁定ShouldBindBodyWith

ShouldBindJSON方法是最常用解析JSON數(shù)據(jù)的方法之一,但在重復(fù)調(diào)用的情況下會(huì)出現(xiàn)EOF的報(bào)錯(cuò),這個(gè)原因出在ShouldBindJSON在調(diào)用過一次之后context.request.body.sawEOF的值是false導(dǎo)致,所以如果要多次綁定多個(gè)變量,需要使用ShouldBindBodyWith。

至于為什么單次綁定不優(yōu)選使用BindJSON方法,主要因?yàn)锽indJSON方法會(huì)強(qiáng)制拋出錯(cuò)誤,影響正常流程。

以下為范例:

// 以下是用于存儲(chǔ)JSON數(shù)據(jù)的結(jié)構(gòu)體
type MsgJson struct {
	Msg string `json:"msg"`
}
// 單次綁定使用 ShouldBindJSON 方法
func bindExample(c *gin.Context) {
    // ---> 聲明結(jié)構(gòu)體變量
	var a MsgJson
	// ---> 綁定數(shù)據(jù)
	if err := c.ShouldBindJSON(&a); err != nil {
		c.AbortWithStatusJSON(
			http.StatusInternalServerError,
			gin.H{"error": err.Error()})
		return
	}
	// --> 返回
	c.JSON(http.StatusOK, gin.H{"msg": "ok"})
	return
}
// 多次綁定優(yōu)先使用 ShouldBindBodyWith 方法
func bindWithRightWay(c *gin.Context) {
    // ---> 聲明兩個(gè)結(jié)構(gòu)體變量用于存儲(chǔ)JSON數(shù)據(jù)
	var a, b MsgJson
	// ---> 第一次解析(注意第二個(gè)參數(shù)是 binding.JSON)
	if err := c.ShouldBindBodyWith(&a, binding.JSON); err != nil {
		c.AbortWithStatusJSON(
			http.StatusInternalServerError,
			gin.H{"error": err.Error()})
		return
	}
	// ---> 第二次解析
	if err := c.ShouldBindBodyWith(&b, binding.JSON); err != nil {
		c.AbortWithStatusJSON(
			http.StatusInternalServerError,
			gin.H{"error": err.Error()})
		return
	}
	// ---> 返回
	c.JSON(http.StatusOK, gin.H{"msg": "ok"})
	return
}

2. EOF錯(cuò)誤復(fù)現(xiàn)

EOF錯(cuò)誤出現(xiàn)在第二次使用ShouldBindJSON方法,在多次綁定的情況下,優(yōu)先使用ShouldBindBodyWith,以下為錯(cuò)誤示范:

type MsgJson struct {
	Msg string `json:"msg"`
}
func main() {
	r := gin.Default()
	r.POST("/v2", bindWithError)
	_ = r.Run("127.0.0.1:9001")
}
func bindWithError(c *gin.Context) {
	var a, b MsgJson
	if err := c.ShouldBindJSON(&a); err != nil {....}
	// ---> 注意,這里會(huì)出現(xiàn)EOF報(bào)錯(cuò)
	if err := c.ShouldBindJSON(&b); err != nil {....}
    .......
	return
}

Postman測(cè)試結(jié)果:

Goland斷點(diǎn)調(diào)試:

3. ShouldBindBodyWith 源碼分析

ShouldBindBodyWith和ShouldBindWith很像,但它保存了requests的Body到上下文,允許Body被繼續(xù)調(diào)用。

注意:這個(gè)方法會(huì)先讀取Body然后綁定,如果只綁定一次,建議使用ShouldBindWith來獲得更好的性能(因?yàn)楹笳邥?huì)直接讀取并寫到指定變量,而沒有寫入上下文)。

func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) {
	var body []byte
	// ---> 先看上下文是否已經(jīng)有Body的Bytes數(shù)據(jù)
	if cb, ok := c.Get(BodyBytesKey); ok {
		if cbb, ok := cb.([]byte); ok {
			body = cbb
		}
	}
	// ---> 如果Body不為空的情況下,讀取Body數(shù)據(jù)并寫入上下文
	if body == nil {
		body, err = ioutil.ReadAll(c.Request.Body)
		if err != nil {
			return err
		}
		c.Set(BodyBytesKey, body)
	}
	return bb.BindBody(body, obj)
}

流程圖

以上就是Golang Gin解析JSON請(qǐng)求數(shù)據(jù)避免出現(xiàn)EOF錯(cuò)誤的詳細(xì)內(nèi)容,更多關(guān)于Golang Gin解析JSON請(qǐng)求數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go1.18?新特性之多模塊Multi-Module工作區(qū)模式

    Go1.18?新特性之多模塊Multi-Module工作區(qū)模式

    這篇文章主要介紹了Go1.18?新特性之多模塊Multi-Module工作區(qū)模式,在 Go 1.18之前,建議使用依賴模塊中的 replace 指令來處理這個(gè)問題,從 Go 1.18開始引入了一種同時(shí)處理多個(gè)模塊的新方法,通過案例給大家詳細(xì)介紹,感興趣的朋友一起看看吧
    2022-04-04
  • 一步步教你編寫可測(cè)試的Go語言代碼

    一步步教你編寫可測(cè)試的Go語言代碼

    相信每位編程開發(fā)者們應(yīng)該都知道,Golang作為一門標(biāo)榜工程化的語言,提供了非常簡(jiǎn)便、實(shí)用的編寫單元測(cè)試的能力。本文通過Golang源碼包中的用法,來學(xué)習(xí)在實(shí)際項(xiàng)目中如何編寫可測(cè)試的Go代碼。有需要的朋友們可以參考借鑒,下面跟著小編一起去學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • Go語言json編碼駝峰轉(zhuǎn)下劃線、下劃線轉(zhuǎn)駝峰的實(shí)現(xiàn)

    Go語言json編碼駝峰轉(zhuǎn)下劃線、下劃線轉(zhuǎn)駝峰的實(shí)現(xiàn)

    這篇文章主要介紹了Go語言json編碼駝峰轉(zhuǎn)下劃線、下劃線轉(zhuǎn)駝峰的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • golang實(shí)現(xiàn)并發(fā)數(shù)控制的方法

    golang實(shí)現(xiàn)并發(fā)數(shù)控制的方法

    下面小編就為大家分享一篇golang實(shí)現(xiàn)并發(fā)數(shù)控制的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • go語言LeetCode題解999可以被一步捕獲的棋子數(shù)

    go語言LeetCode題解999可以被一步捕獲的棋子數(shù)

    這篇文章主要為大家介紹了go語言LeetCode題解999可以被一步捕獲的棋子數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Go?json自定義Unmarshal避免判斷nil示例詳解

    Go?json自定義Unmarshal避免判斷nil示例詳解

    這篇文章主要為大家介紹了Go?json自定義Unmarshal避免判斷nil示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語言框架快速集成限流中間件詳解

    Go語言框架快速集成限流中間件詳解

    這篇文章主要為大家介紹了Go語言框架快速集成限流中間件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 詳解golang中發(fā)送http請(qǐng)求的幾種常見情況

    詳解golang中發(fā)送http請(qǐng)求的幾種常見情況

    這篇文章主要介紹了詳解golang中發(fā)送http請(qǐng)求的幾種常見情況,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Go語言編程中字符串切割方法小結(jié)

    Go語言編程中字符串切割方法小結(jié)

    這篇文章主要介紹了Go語言編程中字符串切割方法小結(jié),所整理的方法都來自字符串相關(guān)的strings包,需要的朋友可以參考下
    2015-10-10
  • go實(shí)現(xiàn)自動(dòng)復(fù)制U盤小工具demo

    go實(shí)現(xiàn)自動(dòng)復(fù)制U盤小工具demo

    這篇文章主要為大家介紹了go實(shí)現(xiàn)自動(dòng)復(fù)制U盤小工具demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評(píng)論