6

リクエスト本文に対してjsonスキーマ検証を行うミドルウェアを作成しようとしています。検証後、リクエストボディを再度使用する必要があります。しかし、これを行う方法がわかりません。この投稿を参照 して、ボディにアクセスする方法を見つけました。しかし、リクエスト ボディが使用されたら、次の関数で使用できるようにする必要があります。

サンプルコードは次のとおりです。

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"
}
4

3 に答える 3

7

Thellimist が言ったことですが、より多くの言葉で。

ボディを「キャッチして復元」する必要があります。Body はバッファです。つまり、一度読むと消えてしまいます。そのため、キャッチして「元に戻す」と、再びアクセスできます。

この回答を確認してください。これがあなたが探しているものだと思います: https://stackoverflow.com/a/47295689/3521313

于 2017-11-15T19:21:50.167 に答える
0

ミドルウェア内に req.Body をコピーできます。io.TeeReader + bytes.Bufferを確認してください。

私の知る限り、io.Readerを直接コピーすることはできないため、読み取り中にコピーしてから、コピーしたものを割り当てて、c.Request.Body使用できるようにする必要がありますc.Bind

よくわかりませんが、これで作業が楽になるかもしれません。

于 2015-08-15T12:42:30.567 に答える