温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Gin框架中bind怎么使用

发布时间:2021-12-12 09:44:04 来源:亿速云 阅读:378 作者:iii 栏目:开发技术

本篇内容主要讲解“Gin框架中bind怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Gin框架中bind怎么使用”吧!

    概述

    Gin框架中,有bind函数可以非常方便的将url的查询参数query parameter、http的Header,body中提交上来的数据格式,如form,json,xml等,绑定到go中的结构体中去,这期间Binding做了啥事情,这么多个Bindding函数,我们该如何选择,一起通过源码来解开其中神秘的面纱吧。

    Binding接口

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

    Binding是一个接口,在源码中,有10个实现了Binding的结构体,以及3个接口

    Gin框架中bind怎么使用 

    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最终也是调用了SouldBindWith,并且对ShouldBindWith的结果进行了判断,如果有错误,则以http 400的状态码进行退出。

    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)
    }

    这个方法是所有其他绑定方法的一个基础,基本上所有的绑定方法都需要用到这个方法来对数据结构进行一个绑定

    以上为主要的bingding的过程,其他派生出来的如BindJSON、ShouldBindJSON等,为具体的数据类型的快捷方式而已,只是帮我们把具体的bingding的数据类型提前给封装了起来而已,如Json格式的bingding函数

    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())

    这一句是为了判断当前的请求方法和contentType,来给context.MustBindWith传的一个具体的bingding类型。

    Json的实现的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结构体实现了Binding接口的Bind方法,将请求过来的Body数据进行解码,绑定到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其实就是ShouldBindWith(obj, binding.JSON)的快捷方式,简单来说,就是在ShouldBindWith(obj, binding.JSON)上面固定了参数,当我们明确规定,body提交的参数内容为json时,简化了我们的调用和增强了代码的可读性。

    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的方式不一样,不需要传入一个实现Binding接口的结构体类型

    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也是对ShouldBindUri的一个封装,多了一个对ShouldBindUri结果的一个判断 代码实例

    代码如下

    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")
    }

    运行结果

    绑定Header数据

    Gin框架中bind怎么使用

    绑定QueryParameter数据

    Gin框架中bind怎么使用

    绑定Body Json数据

    Gin框架中bind怎么使用

    绑定Uri数据

    Gin框架中bind怎么使用

    到此,相信大家对“Gin框架中bind怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI