首页后端开发其他后端知识Gin框架中bind函数用来做什么,用法是怎样的

Gin框架中bind函数用来做什么,用法是怎样的

时间2024-03-26 06:58:03发布访客分类其他后端知识浏览1423
导读:这篇文章主要介绍了title,小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望大家通过这篇文章可以有所收获。 概述 Gin框架中,有bind函数可以非常方便的将url的查询参数query parameter、...
这篇文章主要介绍了title,小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望大家通过这篇文章可以有所收获。

概述

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个接口

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数据

绑定QueryParameter数据

绑定Body Json数据

绑定Uri数据

总结

  • 使用gin框架中的bind方法,可以很容易对http请求过来的数据传递到我们的结构体指针去,方便我们代码编程。
  • 当参数比较简单,不需要结构体来进行封装时候,此时还需采用context的其他方法来获取对应的值
  • gin在bind的时候,未对结构体的数据进行有效性检查,如果对数据有强要求时,需要自己对结构体的数据内容进行判断
  • 建议在实践过程中,使用shouldBindxxx> 函数

以上就是关于“Gin框架中bind函数用来做什么,用法是怎样的”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注网络,小编每天都会为大家更新不同的知识。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Gin框架中bind函数用来做什么,用法是怎样的
本文地址: https://pptw.com/jishu/653334.html
使用PHP怎样做有干扰素的验证码功能? 基于PHP怎样用openssl扩展实现加密?

游客 回复需填写必要信息