go gin 框架下的數據解析與綁定


技術概述

本博客介紹使用gin框架完成基礎的數據解析與綁定功能,以及列舉出一些比較容易踩的坑。主要內容包括:json數據解析與綁定,表單數據解析與綁定,url數據解析與綁定

技術詳述

1. json數據解析與綁定

先看官方文檔中的源代碼:

// 定義接收數據的結構體
type Login struct {
   User    string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
   Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}

func main() {
   r := gin.Default()
   // JSON綁定
   r.POST("loginJSON", func(c *gin.Context) {
      var json Login
      // 將request的body中的數據,自動按照json格式解析到結構體
      if err := c.ShouldBindJSON(&json); err != nil {
         // 返回錯誤信息
         // gin.H封裝了生成json數據的工具
         c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
         return
      }
      // 判斷用戶名密碼是否正確
      if json.User != "root" || json.Pssword != "admin" {
         c.JSON(http.StatusBadRequest, gin.H{"status": "304"})
         return
      }
      c.JSON(http.StatusOK, gin.H{"status": "200"})
   })
   r.Run(":8000")
}

這是一個簡單的獲取json中的賬號密碼,並進行驗證的例子。從該例子中可以看出:

  • 獲取json數據時不必通過輸入json中每個key值來獲得對應的數據
  • 結構體需要與獲取json的格式相對應
  • 返回結果可以使用gin框架中封裝的方法
  • post方法中需要一個與上下文(context)有關的參數,用於接收前端發來的json數據

於是,我們可以:

  1. 將service服務的結構體中的數據與需要從前端獲取的參數一一對應,而刪除掉多余的數據
  2. 聲明一個函數用於json數據獲取,解析與綁定,並調用相應的服務,將 c *gin.Context作為方程的參數
  3. 將service服務的結構體與接收的json進行綁定
  4. 調用service服務處理數據
  5. 返回結果

下面用一個比較完整的程序片段來闡述具體用法:

  • service結構體中的數據

    type CreateTeamService struct {
    	model.TeamRepositoryInterface // 聲明了具體操作數據庫創建團隊的接口
    	Name          string `form:"name" json:"name" binding:"required"`
    	GroupLeaderID int    `form:"group_leader_id" json:"group_leader_id" binding:"required"`
    	ClassID       int    `form:"class_id" json:"class_id" binding:"required"`
    }
    
  • post方法響應請求

    	// 創建團隊
    	v1.POST("team/create", api.CreateTeam)
    
  • json數據解析與綁定具體函數

    func CreateTeam(c *gin.Context) { // 該函數與CreateTeamService服務在不同的文件中
    	var service service.CreateTeamService
    	if err := c.ShouldBind(&service); err == nil {
            // 實例化接口
    		service.TeamRepositoryInterface = &model.Repo
    		res := service.CreateTeam()
    		c.JSON(http.StatusOK, res)
    	} else {
    		c.JSON(http.StatusOK, ErrorResponse(err))
    	}
    }
    

可以看出,大致過程與上述官方文檔中的用例一致。

2. 表單數據解析和綁定

具體代碼與json數據解析與綁定幾乎完全一致,不同處僅僅在於將ShouldBindJSON()方法換成了Bind()方法。

這也是gin框架的強大之處,即面對不同的前端數據有統一的代碼處理方法。其本質上,還是將表單數據中每個數據的key值與結構中的數據一一對應。

  • 表單結構示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <form action="http://localhost:8000/loginForm" method="post" enctype="application/x-www-form-urlencoded">
            用戶名<input type="text" name="username"><br>
            密碼<input type="password" name="password">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    
  • 結構體示例

    type Login struct {
        // binding:"required"修飾的字段,若接收為空值,則報錯,是必須字段
        User    string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
        Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
    }
    

3. URI數據解析和綁定

具體代碼與上述兩種方式大致相同,同樣地,需要將ShouldBindJSON()方法換成ShouldBindUri方法。

除此之外,需要注意獲取api參數的方法,在此僅介紹最簡單的一種方法:

  • 獲取api參數代碼

    (測試url:localhost:8080/user/烏雞/805376577.com

     r.GET("/user/:name/*action", func(c *gin.Context) {
            name := c.Param("name")
            action := c.Param("action")
            //截取/
            action = strings.Trim(action, "/")
            c.String(http.StatusOK, name+" is "+action)
        })
    

輸出結果:烏雞 is 805376577.com

注意事項&最佳實踐

  1. 一定要在使用service服務的函數中實例化結構體中的接口,不然會報空指針的錯誤
  2. 注意結構體中的數據類型,嚴格按照接口文檔中的數據類型設計,同時,在“json”或“form“屬性中填入相應的”key“值,做到一一對應
  3. 一定要在接收數據時加入判錯處理
  4. 最好不要在一個函數中調用兩個service服務(實際上也很難做到)
  5. 返回給前端的結果可以考慮用http.StatusOK替代200

總結

gin框架給代碼的編寫帶來了諸多方便,不僅代碼簡單友好,並且在程序出錯的情況下也可以通過報錯快速找到解決措施,因為gin的報錯都很詳細,我推薦使用go語言可以多多使用gin框架。

雖然網上gin的官方文檔都介紹的比較詳細,但是關於gin的個人教程以及問答帖子在國內的數量比較少,所以有時候出了問題比較難在網上直接找到解決方法。好在gin語法簡單,只要有一定編程基礎,應該都能夠獨立解決大部分問題。

參考文檔

http://www.topgoer.com/gin框架/gin路由/api參數.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM