杜松子酒 - Go lang如何使用Context.Request.Body并保留它?

时间:2015-08-14 11:11:43

标签: go go-gin

我正在尝试编写一个中间件,我将对请求体进行json模式验证。验证后,我需要再次使用请求体。但我无法弄清楚如何做到这一点。我提到this post 并找到了进入身体的方法。但是一旦使用了请求体,我就需要将它用于我的下一个函数。

以下是示例代码:

package main
import (
        "fmt"
        "io/ioutil"
        "net/http"
        "github.com/gin-gonic/gin"
        //"github.com/xeipuuv/gojsonschema"
)

func middleware() gin.HandlerFunc {
 return func(c *gin.Context) {

    //Will be doing json schema validation here

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

    fmt.Printf("%s \n", string(x))

    fmt.Println("I am a middleware for json schema validation")

    c.Next()
    return
 }
}    

type E struct {
 Email    string
 Password string
}

func test(c *gin.Context) {

 //data := &E{}
 //c.Bind(data)
 //fmt.Println(data)   //prints empty as json body is already used

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

 fmt.Printf("body is: %s \n", string(x))
 c.JSON(http.StatusOK, c)

}

func main() {

 router := gin.Default()

 router.Use(middleware())

 router.POST("/test", test)

 //Listen and serve
 router.Run("127.0.0.1:8080")

}

当前输出:

{
    "email": "test@test.com",
    "password": "123"
} 

I am a middleware for json schema validation
body is: 

预期产出:

{
    "email": "test@test.com",
    "password": "123"
} 
I am a middleware for json schema validation
body is: {
    "email": "test@test.com",
    "password": "123"
}

2 个答案:

答案 0 :(得分:3)

Thellimist说了什么,但更多的话。

你需要“捕获并恢复”身体。 Body是一个缓冲区,这意味着一旦你阅读它,它就消失了。所以,如果你抓住它并“放回去”,你可以再次访问它。

检查这个答案,我认为这就是你要找的: https://stackoverflow.com/a/47295689/3521313

答案 1 :(得分:0)

如果您想多次使用身体内容,并且还使用gin-gonic,我想您正在寻找ShouldBindBodyWith函数。

  

ShouldBindBodyWith与ShouldBindWith相似,但是它将请求正文存储到上下文中,并在再次调用时重用。

     

注意:此方法在绑定之前读取正文。因此,如果只需要调用一次,则应该使用ShouldBindWith以获得更好的性能。

参考文献: