Gin框架---参数获取和绑定

获取Query参数

Query参数又叫Querystring参数,是URL的?后面的一串字符串。

demo代码如下:
r.GET("/home", func(c *gin.Context) {
		username := c.Query("username")
		password := c.DefaultQuery("password", "******")
		addr := c.QueryArray("addr")
		class := c.QueryMap("class")
		age, ok := c.GetQuery("age")
    
		if ok != true {
			fmt.Println(ok)
		}

		c.JSON(http.StatusOK, gin.H{
			"username": username,
			"password": password,
			"addr":     addr,
			"class":    class,
			"age":      age,
		})
	})
结果如下:
image-20230328201715768 image-20230328201949671

总结:

  1. Query()用来获取参数

  2. 使用DefaultQuery()方法时,如果没有相应的参数,就会使用defaultValue的值来代替。

  3. QueryArray()和QueryMap()方法分别获取切片类型和字典类型的参数

  4. GetQuery()方法返回两个值,一个value,一个bool值。当能够获取到相应的值时,bool值=true;当不能够获取到相应的值时,value为空,bool值=false。

  5. 需要注意的是切片类型的参数和字典类型的参数的写法。

    • 切片:addr=aaa&addr=bbb
    • 字典:class[专业]=软件工程&class[年级]=大一

获取Path参数

Path参数就是路径参数,也就是URL中斜杠和斜杠之间的参数

demo代码如下:
r.GET("/user/info/:username/:password/:hobby", func(c *gin.Context) {
		username := c.Param("username")
		password := c.Param("password")
		hobby := c.Param("hobby")
		params := c.Params

		c.JSON(http.StatusOK, gin.H{
			"username": username,
			"password": password,
			"hobby":    hobby,
			"params":   params,
		})
	})
结果如下:
image-20230328205658430

总结:

  1. 把获取的Path参数的前面加上“ : ”,就表示这个Path参数是要获取的参数。

  2. Param()方法只能一个一个的获取参数。

  3. Params()方法是一次性获取所有的Path参数,返回的是Params类型,该类型的定义如下

    type Param struct {
    	Key   string
    	Value string
    }
    
    type Params []Param
    
  4. 当有一部分Path参数获取不到时,前面获取到的Path参数都会全部丢弃。其本质原因是底层使用rang遍历所有的Path参数,如果没有相应的参数,会把整个params切片置为空。源码如下:

    func (ps Params) Get(name string) (string, bool) {
       for _, entry := range ps {
          if entry.Key == name {
             return entry.Value, true
          }
       }
       return "", false //注意:并不是将entry.Value置为nil,而是将整个切片置为空。
    }
    
    func (ps Params) ByName(name string) (va string) {
       va, _ = ps.Get(name)
       return
    }
    
    func (c *Context) Param(key string) string {
    	return c.Params.ByName(key)
    }
    

获取Form表单参数

Demo代码如下:
r.POST("/info", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.DefaultPostForm("password", "******")
		hobby := c.PostFormArray("hobby")
		sex, ok := c.GetPostForm("sex")
		if ok != true {
			fmt.Println(ok)
		}

		c.JSON(http.StatusOK, gin.H{
			"username": username,
			"password": password,
			"sex":      sex,
			"hobby":    hobby,
		})
	})
结果如下:
image-20230329140639480 image-20230329140320814

总结:

  1. PostForm()方法获取表单参数
  2. 使用DefaultPostForm()方法如果没有获取到参数,会有默认值代替
  3. PostFormArray()获取数组对象的表单参数
  4. GetPostForm()方法返回两个值,第一个是表单参数,第二个是bool值

获取Json参数

Demo代码如下:
r.POST("/json", func(c *gin.Context) {
		var m map[string]interface{}
		body, err := c.GetRawData() //从请求体(body)中获取json数据
		if err != nil {
			fmt.Println(err.Error())
		}
		err = json.Unmarshal(body, &m)
		if err != nil {
			fmt.Println(err.Error())
		}
		name := m["name"]
		email := m["email"]

		c.JSON(http.StatusOK, gin.H{
			"name":  name,
			"email": email,
		})
	})
结果如下:
image-20230329163925637

总结:

  1. GetRawData()方法是从请求体(body)中获取原始的json数据

  2. GetRawData()底层使用ioutil包里面的ReadAll()方法来读取数据,ReadAll()方法底层使用io包里面的ReadAll()函数,ReadAll()函数的源码如下:

    func ReadAll(r Reader) ([]byte, error) {
    	b := make([]byte, 0, 512)
    	for {
    		if len(b) == cap(b) {
    			// Add more capacity (let append pick how much).
    			b = append(b, 0)[:len(b)]
    		}
    		n, err := r.Read(b[len(b):cap(b)])
    		b = b[:len(b)+n]
    		if err != nil {
    			if err == EOF {
    				err = nil
    			}
    			return b, err
    		}
    	}
    }
    

    源码分析可以看这篇文章:

    io.ReadAll 怎样读全部

获取请求头中的数据

Demo代码如下:
r.GET("/header", func(c *gin.Context) {
		token := c.GetHeader("Authorization")
		c.JSON(http.StatusOK, gin.H{
			"Authorization": token,
		})
	})
结果如下:
image-20230329165517194

总结:

  1. GetHeader()方法用于获取请求头信息
  2. 设置请求头的方法有两种:
    • c.Header(“Authorization”, “xxx.yyy.zzz”)
    • c.Writer.Header().Set(“Authorization”, “xxx.yyy.zzz”)

数据绑定

基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。 下面的示例代码演示了BindJSON()和ShouldBindJSON,它能够基于请求自动提取JSON类型的数据,并把值绑定到指定的结构体对象。

Demo代码如下:
type Login struct {
	Username string `json:"username"`
	Password string `json:"password"`
}
r.GET("/bindJson", func(c *gin.Context) {
		var login Login
		err := c.BindJSON(&login)
		if err != nil {
			fmt.Println(err.Error())
		}
		username := login.Username
		password := login.Password
		c.JSON(http.StatusOK, Login{
			Username: username,
			Password: password,
		},
		)
	})

r.GET("/shouldBindJson", func(c *gin.Context) {
		var login Login
		err := c.ShouldBindJSON(&login)
		if err != nil {
			fmt.Println(err.Error())
		}
		username := login.Username
		password := login.Password
		c.JSON(http.StatusOK, Login{
			Username: username,
			Password: password,
		},
		)
	})
结果如下:
image-20230329183020139

总结:

  1. 数据绑定是利用结构体的反射机制来实现的,只要结构体里面有相应的Tag标签,就能实现对应数据类型的绑定。

  2. ShouldBindxxx和Bindxxx区别:如果Bindxxx没有绑定到数据,会在Header中添加400的返回信息,而ShouldBindxxx不会。验证结果如下:

    image-20230329183543576
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值