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请求体取值的资料请关注脚本之家其它相关文章!

相关文章

  • golang微服务框架kratos实现Socket.IO服务的方法

    golang微服务框架kratos实现Socket.IO服务的方法

    本文主要介绍了golang微服务框架kratos实现Socket.IO服务的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Go语言自定义linter静态检查工具

    Go语言自定义linter静态检查工具

    这篇文章主要介绍了Go语言自定义linter静态检查工具,Go语言是一门编译型语言,编译器将高级语言翻译成机器语言,会先对源代码做词法分析,词法分析是将字符序列转换为Token序列的过程,文章详细介绍需要的小伙伴可以参考一下
    2022-05-05
  • GO语言延迟函数defer用法详解

    GO语言延迟函数defer用法详解

    本文主要介绍了GO语言延迟函数defer用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • golang对自定义类型进行排序的解决方法

    golang对自定义类型进行排序的解决方法

    学习一门编程语言,要掌握原子数据类型,还需要掌握自定义数据类型。下面这篇文章主要给大家介绍了关于golang如何对自定义类型进行排序的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-12-12
  • 深入了解Golang为什么需要超时控制

    深入了解Golang为什么需要超时控制

    本文将介绍为什么需要超时控制,然后详细介绍Go语言中实现超时控制的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-05-05
  • Go语言错误处理异常捕获+异常抛出

    Go语言错误处理异常捕获+异常抛出

    这篇文章主要介绍了Go语言错误处理异常捕获和异常抛出,Go语言的作者认为java等语言的错误处理底层实现较为复杂,就实现了函数可以返回错误类型以及简单的异常捕获,虽然简单但是也非常精妙,大大的提高了运行效率,下文需要的朋友可以参考一下
    2022-02-02
  • Golang中文件目录操作的实现步骤详解

    Golang中文件目录操作的实现步骤详解

    在Golang中,文件目录是指计算机文件系统中的文件夹或目录。目录是用于组织和存储文件的一种方式,可以包含文件和其他子目录,本文主要介绍了Golang中文件目录操作的实现方法,需要的朋友可以参考下
    2023-05-05
  • 一文详解Golang的中间件设计模式

    一文详解Golang的中间件设计模式

    最近在看一些rpc框架的使用原理和源码的时候,对中间件的实现非常感兴趣,所以这篇文章就来和大家聊聊Golang的中间件设计模式,希望对大家有所帮助
    2023-03-03
  • golang NewRequest/gorequest实现http请求的示例代码

    golang NewRequest/gorequest实现http请求的示例代码

    本文主要介绍了golang NewRequest/gorequest实现http请求的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Go日志框架zap增强及源码解读

    Go日志框架zap增强及源码解读

    这篇文章主要为大家介绍了Go日志框架zap增强及源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07

最新评论