gin自定义中间件解决requestBody不可重读(请求体取值)

 更新时间:2023年10月10日 11:25:53   作者:goper  
这篇文章主要介绍了gin自定义中间件解决requestBody不可重读,确保控制器能够获取请求体值,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

使用中间件

注意,这个中间件,需要在第一个执行。

问题复现

type Test struct {
    Test string `json:"test"`
}
func main() {
    ginServer := gin.Default()
    ginServer.POST("/test", func(ctx *gin.Context) {
        //中间件取值
        var test Test
        ctx.BindJSON(&test)
        fmt.Printf("inteceptor %v\n", test)
        ctx.Next()
    }, func(ctx *gin.Context) {
        //controller取值
        var test Test
        ctx.BindJSON(&test)
        fmt.Printf("controller %v\n", test)
    })
}

结果

【中间件】从request.body里取值后,【controller】会取不到值 

其他方式解决方案

方法一:使用context.ShouldBindBodyWith() (推荐)

个人推荐这个方法,更简单

官网详细文档:将 request body 绑定到不同的结构体中 | 示例 |《Gin 框架中文文档 1.7》| Go 技术论坛 (learnku.com)

用例:

ctx.ShouldBindBodyWith(&test,binding.JSON)

测试完整代码:

type Test struct {
    Test string `json:"test"`
}
func main() {
    ginServer := gin.Default()
    ginServer.POST("/test", func(ctx *gin.Context) {
        //中间件取值
        var test Test
        //修改此处
        ctx.ShouldBindBodyWith(&test, binding.JSON)
        fmt.Printf("inteceptor %v\n", test)
        ctx.Next()
    }, func(ctx *gin.Context) {
        //controller取值
        var test Test
        //修改此处
        ctx.ShouldBindBodyWith(&test, binding.JSON)
        fmt.Printf("controller %v\n", test)
    })
}
       

 方法二:使用context.Set()/Get()

也可以使用【Session】或者其他方式完成,思路就是取完又存

具体详看: 

Gin:Session

//中间件存值
func(ctx *gin.Context) {
        var test Test
        ctx.BindJSON(&test)
        ctx.Set("test", test)
        ctx.Next()
}
//controller取值
func(ctx *gin.Context) {
        var test Test
        value, _ := ctx.Get("test")
        test=value.(Test)
        fmt.Printf("controller %v\n", test)
}
    

方法三:读取body内容

 思路同样是取完又存

读取:

data, _ := ioutil.ReadAll(c.Request.Body)

bind对象:var data model.Post

c.BindJSON(&data)

写入:

c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data))

参考总结方式

r := gin.Default()
    // 注册中间件,使body可以重复读取
    r.Use(func(context *gin.Context) {
        all, err := context.GetRawData() // 读取body的内容
        if err != nil {
            log.Fatal(err)
        }
        // 重写 GetBody 方法,以便后续的其他操作
        context.Request.GetBody = func() (io.ReadCloser, error) {
            context.Request.Body = io.NopCloser(bytes.NewBuffer(all))
            buffer := bytes.NewBuffer(all)
            closer := io.NopCloser(buffer)
            return closer, nil
        }
        body, _ := context.Request.GetBody()  // 每次调用GetBody方法,都会新生成一个io.ReadCloser,但是底层的byte数据,都是all变量缓存的。
        context.Request.Body = body
        context.Next()
    })

以上就是gin自定义中间件解决requestBody不可重读(请求体取值)的详细内容,更多关于gin requestBody请求体取值的资料请关注脚本之家其它相关文章!

相关文章

  • GO中的时间操作总结(time&dateparse)

    GO中的时间操作总结(time&dateparse)

    日常开发过程中,对于时间的操作可谓是无处不在,但是想实现时间自由还是不简单的,多种时间格式容易混淆,本文为大家整理了一下GO中的时间操作,有需要的可以参考下
    2023-09-09
  • Go语言计算指定年月天数的方法

    Go语言计算指定年月天数的方法

    这篇文章主要介绍了Go语言计算指定年月天数的方法,实例分析了Go语言操作时间的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go gRPC服务进阶middleware使用教程

    Go gRPC服务进阶middleware使用教程

    这篇文章主要为大家介绍了Go gRPC服务进阶middleware的使用教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 详解为什么说Golang中的字符串类型不能修改

    详解为什么说Golang中的字符串类型不能修改

    在接触Go这么语言,可能你经常会听到这样一句话。对于字符串不能修改,可能你很纳闷,日常开发中我们对字符串进行修改也是很正常的,为什么又说Go中的字符串不能进行修改呢?本文就来通过实际案例给大家演示一下
    2023-03-03
  • Golang中switch语句和select语句的用法教程

    Golang中switch语句和select语句的用法教程

    这篇文章主要给大家介绍了关于Golang中switch和select的用法教程,文中通过示例代码将switch语句与select语句的使用方法介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • GoLand利用plantuml生成UML类图

    GoLand利用plantuml生成UML类图

    本文主要介绍了GoLand利用plantuml生成UML类图,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 利用Go语言实现二叉搜索树

    利用Go语言实现二叉搜索树

    二叉树是一种常见并且非常重要的数据结构,在很多项目中都能看到二叉树的身影,当然它也有很多变种,本文要介绍的是二叉搜索树的实现,希望对大家有所帮助
    2023-07-07
  • Golang实现超时退出的三种方式

    Golang实现超时退出的三种方式

    这篇文章主要介绍了Golang三种方式实现超时退出,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • Golang设计模式之原型模式详细讲解

    Golang设计模式之原型模式详细讲解

    如果一个类的有非常多的属性,层级还很深。每次构造起来,不管是直接构造还是用建造者模式,都要对太多属性进行复制,那么有没有一种好的方式让我们创建太的时候使用体验更好一点呢? 今天的文章里就给大家介绍一种设计模式,来解决这个问题
    2023-01-01
  • golang解析域名的步骤全纪录

    golang解析域名的步骤全纪录

    这篇文章主要给大家介绍了利用golang如何解析域名的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-12-12

最新评论