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 Web Dynpro - 个性化和配置
根据业务需求,您可以实现许多标准应用程序,并且Web Dynpro应用程序的UI可以根据要求而有所不同. 应用配置 要配置Web Dynpro应用程序,首先要为单个Web Dynpro组件配置数据记录 ...
- SAP 实例 3 Context Menus
REPORT demo_dynpro_context_menu. DATA: field1 TYPE i VALUE 10, field2 TYPE p DECIMALS 4. DATA: prog ...
- Elasticsearch学习系列四(聚合搜索)
聚合分析 聚合分析是数据库中重要的功能特性,完成对一个查询的集中数据的聚合计算.如:最大值.最小值.求和.平均值等等.对一个数据集求和,算最大最小值等等,在ES中称为指标聚合,而对数据做类似关系型数据 ...
- centos 7安装zabbix
1 升级系统组件到最新版本 yum -y update 2 关闭 SELinux sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" / ...
- Java实现无界面计算器
## 要求### 1.四个方法加减乘除### 1.循环加switch### 1.传递2个数源码如下: ``` public class Jisuanqi { public static void ma ...
- 全网求解,用Python处理一个基础题目
昨天在群里看见一个Python的问题,趁着今天有那么一点点时间,就想把这个题目分享出来,让大家一起解决.毕竟三个臭皮匠,赛过诸葛亮.原始数据如下: 1 origin_lst = [0, 0, 1, 2 ...
- 智能指针思想实践(std::unique_ptr, std::shared_ptr)
1 smart pointer 思想 个人认为smart pointer实际上就是一个对原始指针类型的一个封装类,并对外提供了-> 和 * 两种操作,使得其能够表现出原始指针的操作行为. ...
- 聊聊 C++ 中的几种智能指针 (下)
一:背景 上一篇我们聊到了C++ 的 auto_ptr ,有朋友说已经在 C++ 17 中被弃用了,感谢朋友提醒,今天我们来聊一下 C++ 11 中引入的几个智能指针. unique_ptr shar ...
- 浅析golang shellcode加载器
最近也是学习了一下有关shellcode进程注入的操作,简单分享一下通过golang进行实现shellcode加载器的免杀思路. 杀软的查杀方式 静态查杀:查杀的方式是结合特征码,对文件的特征段如Ha ...
- git常见问题及解决方法
简介 由于在git使用过程中会出现各种各样的问题,因此本文将常见的问题记录下来并提供相应的解决方案,方便后续查找. git pull问题: There is no tracking informati ...