2015-08-14 29 views
1

我正在尝试编写一个中间件,我将对请求主体进行json模式验证。验证之后,我需要再次使用请求主体。但我无法弄清楚如何做到这一点。我提到了this post 并找到了一种访问正文的方法。但是一旦使用了请求主体,我就需要将它提供给我的下一个功能。Gin - Go lang如何使用Context.Request.Body并保留它?

下面是示例代码:

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 protected]”, “密码”: “123” } 我我对JSON模式验证中间件 体是:

预期输出:

{ “电子邮件”: “[email protected]”, “密码”: “123” } 我为JSON模式验证中间件 体是:{ “电子邮件”:“[email protected] “, ”password“:”123“ }

+0

https://play.golang.org/p/N_553jVAIX显示在HTTP复制的'io.ReadCloser'的几种变化处理程序。需要在身体和预期身材上做些什么的细节才能在他们之间选择。 –

回答

0

您可以将req.Body复制到您的中间件中。退房io.TeeReader + bytes.Buffer

据我知道你不能直接复制io.Reader所以你必须在你读它,然后分配复制一回c.Request.Body,以便能够使用它c.Bind

我把它复制米不知道,但也许this可以让事情变得更容易。

1

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

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

检查这个答案,我认为这是你在找什么: https://stackoverflow.com/a/47295689/3521313