2015-08-14 57 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