为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Context.Request.Body 并保留它?

如何使用 Context.Request.Body 并保留它?

Go
慕森王 2021-11-01 15:12:10
我正在尝试编写一个中间件,我将对请求正文进行 json 模式验证。验证后,我需要再次使用请求正文。但我无法弄清楚如何做到这一点。我参考了这篇文章 并找到了一种访问身体的方法。但是一旦使用了请求正文,我就需要它可用于我的下一个函数。这是示例代码:package mainimport (        "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 validationbody is: 预期输出:{    "email": "test@test.com",    "password": "123"} I am a middleware for json schema validationbody is: {    "email": "test@test.com",    "password": "123"}
查看完整描述

3 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

Thellimist 所说的,不过是更多的话。

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


查看完整回答
反对 回复 2021-11-01
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

您可以在中间件中复制 req.Body。查看io.TeeReader + bytes.Buffer

据我所知,您不能直接复制 io.Reader,因此您必须在阅读时复制它,然后将复制的副本分配回以便c.Request.Body能够将其用于c.Bind

我不确定,但也许可以让事情变得更容易。


查看完整回答
反对 回复 2021-11-01
  • 3 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信