gin如何多次shoubind一个请求参数
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一个请求参数的更多相关文章
- 我的Android进阶之旅------>android如何将List请求参数列表转换为json格式
本文同步发表在简书,链接:http://www.jianshu.com/p/395a4c8b05b9 前言 由于接收原来的老项目并进行维护,之前的http请求是使用Apache Jakarta Com ...
- SpringBoot系列教程web篇之Get请求参数解析姿势汇总
一般在开发web应用的时候,如果提供http接口,最常见的http请求方式为GET/POST,我们知道这两种请求方式的一个显著区别是GET请求的参数在url中,而post请求可以不在url中:那么一个 ...
- JMeter 将上一个请求的结果作为下一个请求的参数——使用正则提取器(转载)
在接口测试和压力测试过程中,经常会将几个流程串联起来才能测试.如:我要进行获取用户信息接口测试,我就要先登录成功后,才能获取用户信息.所以,我就要首先要登录,获得我的登录凭证(tokenId或tick ...
- jmeter 如何将上一个请求的结果作为下一个请求的参数——使用正则提取器
1.简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可以用于测试静态和动态资源例如 ...
- Jmeter如何将上一个请求的结果作为下一个请求的参数——使用正则表达式提取器
首先在线程组下添加两个HTTP请求, 添加好两个HTTP请求后,在每个HTTP请求下添加一个查看结果数 在第一个HTTP请求下添加正则表达式提取器 在第一个HTTP请求添加好IP地址,路径,端口号,协 ...
- jmeter将上一个接口返回值作为下一个接口的请求参数
在jmeter中有时候会用到,将上一个接口的返回值作为下一个接口的请求参数 具体操作如下: 1.首先新建一个http请求(右键线程组--添加Sampler--http请求),同时添加好接口相应的请求参 ...
- 关于 HTTP GET/POST 请求参数长度最大值的一个理解误区(转载)
1. Get方法长度限制 Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制.这个限制是特定的浏览器及服务器对它的限制.下面就是对各种浏览器和服务器的最大处理能 ...
- JMeter 如何把上一个请求的结果作为下一个请求的参数 —— 使用正则提取器
有这样一个压力测试环境,有一个上传页面,上传成功之后服务器会返回一些上传信息(比如文件的 id 或者保存路径之类的信息),然后压力机会继续下一个请求,比如调整 id 为 xx 的文件的一些信息等等.问 ...
- 关于 HTTP GET/POST 请求参数长度最大值的一个理解误区
1. Get方法长度限制 Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制.这个限制是特定的浏览器及服务器对它的限制. 如:IE对URL长度的限制是20 ...
随机推荐
- SAP APO-供应链监控
供应链监控(SCM)是一种有效的工具,可以为供应商和购买者做出明智的决策. 供应链流程中的关键人物基于供应链监控做出决策. 供应链包括两个工具- 库存需求清单MD04 物流信息系统(LIS) 事务MD ...
- IDEA快速创建maven项目
遇到问题不要急,不要怕. 一. 二. 三. 四.Finish进来之后,项目会加载一会,之后会是下面这样子. 五.继续往下面配置,建立java和resorces文件夹 六.下面配置tomcat服 ...
- idea 在创建maven时没有src的解决方法
在创建maven时 加上archetypeCatalog=internal
- 攻防世界pwn题:Recho
0x00:查看文件信息 一个64位二进制文件,canary和PIE保护机制没开. 0x01:用IDA进行静态分析 分析:主程序部分是一个while循环,判断条件是read返回值大于0则循环.函数ato ...
- 纪念我逝去的n个小时
纪念我逝去的n个小时 某人的惨案要我擦屁股=.= #include <bits/stdc++.h> using namespace std; template<class T> ...
- APISpace 让你快速获取名言警句
名言警句,是指一些名人说的.写的.历史纪录的.经过实践所得出的结论或建议.警示的比较有名的言语.名言警句易于留传. 名言警句API,涵盖人生.励志等多个方面. APISpace 有很多免费通用 ...
- Template -「平衡树」
Fhq-Treap. // Fhq-Treap const int MAXN = 1e5 + 5; struct Fhq_Treap { #define Lson Tr[p].l #define Rs ...
- Solution -「CF520E」Pluses everywhere
Step 1. 转化一步题目:考虑有 \(n\) 个小球,每个小球有 \(a_i\) 的价值,\(m\) 个板子,把板子插进小球间的空隙,且不能插在第 \(1\) 个球之前与第 \(n\) 个球之后. ...
- 【Azure 事件中心】Azure Event Hub 新功能尝试 -- 异地灾难恢复 (Geo-Disaster Recovery)
问题描述 关于Event Hub(事件中心)的灾备方案,大多数就是新建另外一个备用的Event Hub,当主Event Hub出现不可用的情况时,就需要切换到备Event Hub上. 而在切换的过程中 ...
- 基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用
在我们实际项目开发过程中,往往需要根据实际情况,对组件进行封装,以更简便的在界面代码中使用,在实际的前端应用中,适当的组件封装,可以减少很多重复的界面代码,并且能够非常简便的使用,本篇随笔介绍基于El ...