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中的结构体编解码神器Mapstructure库

    详解golang中的结构体编解码神器Mapstructure库

    mapstructure是GO字典(map[string]interface{})和Go结构体之间转换的编解码工具,这篇文章主要为大家介绍一下Mapstructure库的相关使用,希望对大家有所帮助
    2023-09-09
  • Go中基本数据类型和字符串表示之间转换详解

    Go中基本数据类型和字符串表示之间转换详解

    这篇文章主要为大家详细介绍了Go中基本数据类型和字符串表示之间转换的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • Go语言HTTP请求流式写入body的示例代码

    Go语言HTTP请求流式写入body的示例代码

    这篇文章主要介绍了Go语言HTTP请求流式写入body,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 深入解析golang bufio

    深入解析golang bufio

    这篇文章主要介绍了golang bufio解析,golang的bufio库使用缓存来一次性进行大块数据的读写,以此降低IO系统调用,提升性能,需要的朋友可以参考下
    2022-04-04
  • golang通用的grpc http基础开发框架使用快速入门

    golang通用的grpc http基础开发框架使用快速入门

    这篇文章主要为大家介绍了golang通用的grpc http基础开发框架使用快速入门详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Golang接口使用教程详解

    Golang接口使用教程详解

    在 Go 语言中接口包含两种含义:它既是方法的集合, 同时还是一种类型并且在Go 语言中是隐式实现的。本文通过示例详细介绍了Golang接口的使用,需要的可以参考一下
    2022-09-09
  • Go语言实现的最简单数独解法

    Go语言实现的最简单数独解法

    前面给大家介绍过使用javascript实现的简单的数独解法,小伙伴们都非常喜欢,今天我们再来分享一则go语言实现的简单的数独解法,有需要的小伙伴来参考下。
    2015-03-03
  • RabbitMQ延时消息队列在golang中的使用详解

    RabbitMQ延时消息队列在golang中的使用详解

    延时队列常使用在某些业务场景,使用延时队列可以简化系统的设计和开发、提高系统的可靠性和可用性、提高系统的性能,下面我们就来看看如何在golang中使用RabbitMQ的延时消息队列吧
    2023-11-11
  • Golang中Gin框架中如何定义路由详解

    Golang中Gin框架中如何定义路由详解

    Gin是一个用Go语言编写的Web框架,具有高性能和易于使用的特点,本文将结合实际案例,详细介绍Gin框架的路由用法,有需要的小伙伴可以参考下
    2024-10-10
  • Golang实现单链表的示例代码

    Golang实现单链表的示例代码

    本文主要介绍了Golang实现单链表的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03

最新评论