2015-08-14 2 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 показывает несколько вариантов дублируя 'io.ReadCloser' в HTTP обработчик. Подробная информация о том, что делается с телом и ожидаемом размере, потребуется для выбора между ними. –

ответ

0

Вы можете скопировать req.Body внутри вашего промежуточного программного обеспечения. Выезд io.TeeReader + bytes.Buffer.

Насколько я знаю, вы не можете напрямую скопировать io.Reader, так что вы должны скопировать его в то время как вы читаете это, то присвоить скопированное один обратно c.Request.Body, чтобы иметь возможность использовать его для c.Bind

I» м не уверен, но, может быть, this может сделать все проще.

1

Что сказал Thellimist, но более подробно.

Вам нужно «поймать и восстановить» Тело. Тело - это буфер, это означает, что как только вы его прочитали, его ушло. Итак, если вы поймаете его и «вернете», вы сможете получить к нему доступ еще раз.

Проверить этот ответ, я думаю, что это то, что вы ищете: https://stackoverflow.com/a/47295689/3521313