gin多次绑定请求参数

package main

import (
"fmt"
"net/http"
"time" "github.com/gin-gonic/gin"
) // resp 返回
func resp(c *gin.Context, code int, msg string) {
c.JSON(http.StatusOK, gin.H{
"code": code,
"msg": msg,
"nowtime": time.Now().Unix(),
})
} // AuthMiddleware 认证中间件
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 中间件内bind参数
var l loginReq
if err := c.ShouldBind(&l); err != nil {
fmt.Println("err: ", err)
c.Abort()
} if l.UserName == "" && l.Password == "" {
c.Abort()
}
}
} // login 登录逻辑
func login(c *gin.Context) {
// 逻辑内再次bind参数
// 此时这里的shouldBind会出错, 错误是: EOF
var lr loginReq
if err := c.ShouldBind(&lr); err != nil {
fmt.Printf("bind params err: %v\n", err)
resp(c, -1, err.Error())
return
} resp(c, 0, fmt.Sprintf("%s login success!", lr.UserName))
return
} // loginReq 请求参数
type loginReq struct {
UserName string `json:"username"`
Password string `json:"password"`
} func main() {
e := gin.Default()
// 注册全局中间件
e.Use(authMiddleware()) e.POST("/api/v1/login", login) e.Run(":8080")
}

请求验证:

curl -XPOST 'http://127.0.0.1:8080/api/v1/login' \
-H 'Content-Type: application/json' \
-d '{
"username":"zhangsan",
"password":"123456"
}' 响应: {
"code": -1,
"msg": "EOF",
"nowtime": 1662451101
}

一、 使用ShouldBindBodyWith解决

// tips:
// c.ShouldBindBodyWith在绑定之前将 body 存储到上下文中。这对性能有轻微的影响,因此如果您足够一次调用绑定,则不应使用此方法。
package main import (
"fmt"
"net/http"
"time" "github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
) // resp 返回
func resp(c *gin.Context, code int, msg string) {
c.JSON(http.StatusOK, gin.H{
"code": code,
"msg": msg,
"nowtime": time.Now().Unix(),
})
} // AuthMiddleware 认证中间件
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 中间件内bind参数
var l loginReq
if err := c.ShouldBindBodyWith(&l, binding.JSON); err != nil {
fmt.Println("err: ", err)
c.Abort()
} if l.UserName == "" && l.Password == "" {
c.Abort()
}
}
} // login 登录逻辑
func login(c *gin.Context) {
// 逻辑内再次bind参数
// 此时这里的shouldBind不会出错
var lr loginReq
if err := c.ShouldBindBodyWith(&lr, binding.JSON); err != nil {
fmt.Printf("bind params err: %v\n", err)
resp(c, -1, err.Error())
return
} resp(c, 0, fmt.Sprintf("%s login success!", lr.UserName))
return
} // loginReq 请求参数
type loginReq struct {
UserName string `json:"username"`
Password string `json:"password"`
} func main() {
e := gin.Default()
// 注册全局中间件
e.Use(authMiddleware()) e.POST("/api/v1/login", login) e.Run(":8080")
}

二、 转存Body

package main

import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"time" "github.com/gin-gonic/gin"
) // resp 返回
func resp(c *gin.Context, code int, msg string) {
c.JSON(http.StatusOK, gin.H{
"code": code,
"msg": msg,
"nowtime": time.Now().Unix(),
})
} // AuthMiddleware 认证中间件
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 先把body取出来
data, err := c.GetRawData()
if err != nil {
fmt.Println("read body failed, error: ", err)
} // bind之前把body写回去
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data))
var l loginReq
if err := c.ShouldBind(&l); err != nil {
fmt.Println("err: ", err)
c.Abort()
} // bind之后把body写回去
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data))
if l.UserName == "" && l.Password == "" {
c.Abort()
}
}
} // login 登录逻辑
func login(c *gin.Context) {
// 逻辑内再次bind参数
// 此时这里的shouldBind不会出错
var lr loginReq
if err := c.ShouldBind(&lr); err != nil {
fmt.Printf("bind params err: %v\n", err)
resp(c, -1, err.Error())
return
} resp(c, 0, fmt.Sprintf("%s login success!", lr.UserName))
return
} // loginReq 请求参数
type loginReq struct {
UserName string `json:"username"`
Password string `json:"password"`
} func main() {
e := gin.Default()
// 注册全局中间件
e.Use(authMiddleware()) e.POST("/api/v1/login", login) e.Run(":8080")
}

推荐使用第二种方式解决

gin如何多次shoubind一个请求参数的更多相关文章

  1. 我的Android进阶之旅------>android如何将List请求参数列表转换为json格式

    本文同步发表在简书,链接:http://www.jianshu.com/p/395a4c8b05b9 前言 由于接收原来的老项目并进行维护,之前的http请求是使用Apache Jakarta Com ...

  2. SpringBoot系列教程web篇之Get请求参数解析姿势汇总

    一般在开发web应用的时候,如果提供http接口,最常见的http请求方式为GET/POST,我们知道这两种请求方式的一个显著区别是GET请求的参数在url中,而post请求可以不在url中:那么一个 ...

  3. JMeter 将上一个请求的结果作为下一个请求的参数——使用正则提取器(转载)

    在接口测试和压力测试过程中,经常会将几个流程串联起来才能测试.如:我要进行获取用户信息接口测试,我就要先登录成功后,才能获取用户信息.所以,我就要首先要登录,获得我的登录凭证(tokenId或tick ...

  4. jmeter 如何将上一个请求的结果作为下一个请求的参数——使用正则提取器

    1.简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可以用于测试静态和动态资源例如 ...

  5. Jmeter如何将上一个请求的结果作为下一个请求的参数——使用正则表达式提取器

    首先在线程组下添加两个HTTP请求, 添加好两个HTTP请求后,在每个HTTP请求下添加一个查看结果数 在第一个HTTP请求下添加正则表达式提取器 在第一个HTTP请求添加好IP地址,路径,端口号,协 ...

  6. jmeter将上一个接口返回值作为下一个接口的请求参数

    在jmeter中有时候会用到,将上一个接口的返回值作为下一个接口的请求参数 具体操作如下: 1.首先新建一个http请求(右键线程组--添加Sampler--http请求),同时添加好接口相应的请求参 ...

  7. 关于 HTTP GET/POST 请求参数长度最大值的一个理解误区(转载)

    1. Get方法长度限制 Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制.这个限制是特定的浏览器及服务器对它的限制.下面就是对各种浏览器和服务器的最大处理能 ...

  8. JMeter 如何把上一个请求的结果作为下一个请求的参数 —— 使用正则提取器

    有这样一个压力测试环境,有一个上传页面,上传成功之后服务器会返回一些上传信息(比如文件的 id 或者保存路径之类的信息),然后压力机会继续下一个请求,比如调整 id 为 xx 的文件的一些信息等等.问 ...

  9. 关于 HTTP GET/POST 请求参数长度最大值的一个理解误区

    1.    Get方法长度限制 Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制.这个限制是特定的浏览器及服务器对它的限制. 如:IE对URL长度的限制是20 ...

随机推荐

  1. 关闭windows更新、设置自启动、提高开发机性能

    做Java开发的朋友都知道,每次开机启动一堆的软件和工具,包括未写完的文档,是非常花时间的,加上一桌面的快捷方式,往往不是那么容易直接找到.windows的自动更新往往在凌晨自动启动,导致很多软件被异 ...

  2. 利用MATLAB仿真最小发射功率下WSN的连通性和覆盖率

    一.目的 (1)在固定节点个数的前提下,仿真求得使网络保持连通的最小通信半径(最低能级). (2)在上述节点个数和通信半径的前提下,计算随机布撒的节点的覆盖率. 二.方法描述 (1)首先假设通信半径都 ...

  3. JSP页面+请求转发+EL表达式

    1) JSP全称Java Server Pages,顾名思义就是运行在java服务器中的页面,也就是在我们JavaWeb中的动态页面,其本质就是一个Servlet.2) 其本身是一个动态网页技术标准, ...

  4. JDBCToolsV3 :DAO

    编写文件和步骤 ①,bean模块:数据类Course,包含数据的class,封装数据类型; ②,DAO:1)定义对数据的操作接口,及规定标准(包含怎样的操作).例如:CourseDAO数据库操作的接口 ...

  5. HTML基础学习笔记(一)

    简介 基本形式 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...

  6. Solution -「Luogu 4135」作诗

    写在前面 & 前置芝士   好像是好久没有打理 blog 了.感觉上学期是有点颓.嘶,初三了好好冲一次吧.   那么回到这道题目.你会分块就能看懂. 题目大意   先挂个来自洛谷的 link. ...

  7. CSDN 原力(声望,影响力) -- 设计草案

    目标 CSDN 希望成为开发者学习,成长和成就的平台.我们已经有很多功能来支持开发者的职业成长了, 如何衡量成就呢?我们希望用 原力 (以前也叫 影响力,声望) 来体现用户的成就, 并希望用原力来帮助 ...

  8. java 桥接方法

    1.桥接方法简介 桥接方法是jdk1.5引入泛型后,为使java泛型方法生成的字节码与jdk1.5版本之前的字节码兼容由编译器自动生成的. 可用method.isBridge() 判断method是否 ...

  9. 使用marker的一些内容

    因为最近在搞uni-app的地图项目,所以大量使用了uni-app中的地图组件 虽然uni-app还是一个小学生水平,但是自己也想了很多 本期就来谈一谈uni-app中的marker,里面的好的内容和 ...

  10. python 常用的魔法函数

    简介 在实际项目中,我们其实并不会太多的使用魔法函数,但是一些方法或者函数均是有魔法函数演变而来的,且在一些面试过程中会遇到一些关于常见方法的实现,就会牵扯到相应的魔法函数,此处将介绍一些我认为比较常 ...