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 ...
随机推荐
- nginx转发rabbitmq
第一种: 直接加个location块 location /rabbitmq/ { proxy_pass http://127.0.0.1:15672/; } 第二种: location /rabbit ...
- NC15975 小C的记事本
NC15975 小C的记事本 题目 题目描述 小C最近学会了java小程序的开发,他很开心,于是想做一个简单的记事本程序练练手. 他希望他的记事本包含以下功能: 1.append(str),向记事本插 ...
- 网络通讯之Socket-Tcp(二)
网络通讯之Socket-Tcp 分成2部分讲解: 网络通讯之Socket-Tcp(一): 1.如何理解Socket 2.Socket通信重要函数 3.Socket Tcp 调用的基本流程图 4.简单 ...
- 近期碰到的一些面试题--WPF、C#、数据库
最近想换工作的念头特别强烈,面了几家公司没有拿到满意的offer,心仪的公司面完锁HC,有点无奈,感觉今年有点卷,把碰到过的面试题总结下. WPF相关: 1.定义依赖属性需要注意哪些地方? (1)依赖 ...
- NOI / 2.3基本算法之递归变递推-6262:流感传染
OpenJudge - 6262:流感传染http://noi.openjudge.cn/ch0203/6262/ 6262:流感传染 总时间限制: 1000ms 内存限制: 65536k ...
- 【一本通提高树链剖分】「ZJOI2008」树的统计
[ZJOI2008]树的统计 题目描述 一棵树上有 n n n 个节点,编号分别为 1 1 1 到 n n n,每个节点都有一个权值 w w w. 我们将以下面的形式来要求你对这棵树完成一些操作: I ...
- Page和list的区别 mybatis
先看一段代码 点击查看代码 @Override public Result findUserPage(PageParam pageParam) { Page<SysUser> page = ...
- mysql主从复制学习笔记
一.musql主从复制原理 MySQL之间数据复制的基础是二进制日志文件(binary log file).一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以&q ...
- 方法引用_通过this引用本类的成员方法和方法引用_类的构造器(构造方法)引用和数组的构造器引用
package com.yang.Test.ThisMethodReference; /** * 通过this引用本类的成员方法 */ public class Husband { //定义一个买房子 ...
- js for和while两种99乘法表
<script type="text/javascript"> for(var i=1; i<=9; i++) { for(var j=1; j<=i;j+ ...