gin/golang – Empty Req Body

huangapple go评论93阅读模式
英文:

gin/golang - Empty Req Body

问题

我是你的中文翻译助手,以下是翻译好的内容:

我对Go和Gin都不熟悉,遇到了一个问题,无法打印出完整的请求体。

我想要能够从第三方POST请求中读取请求体,但是我得到的请求体是空的。

curl -u dumbuser:dumbuserpassword -H "Content-Type: application/json" -X POST --data '{"events": "3"}' http://localhost:8080/events

我的完整代码如下。非常感谢任何指点!

package main

import (
  "net/http"
  "fmt"
  "github.com/gin-gonic/gin"
)

func main() {
  router := gin.Default()
  authorized := router.Group("/", gin.BasicAuth(gin.Accounts{
     "dumbuser": "dumbuserpassword",
  }))
  authorized.POST("/events", events)
  router.Run(":8080")
}

func events(c *gin.Context) {
  fmt.Printf("%s", c.Request.Body)
  c.JSON(http.StatusOK, c)
}
英文:

I'm new to Go and Gin, and am having trouble printing out the full request body.

I want to be able to read the request body from third party POST, but I'm getting empty request body

curl -u dumbuser:dumbuserpassword -H "Content-Type: application/json" -X POST --data '{"events": "3"}' http://localhost:8080/events

My entire code is as below. Any pointer is appreciated!

package main

import (
  "net/http"
  "fmt"
  "github.com/gin-gonic/gin"
)

func main() {
  router := gin.Default()
  authorized := router.Group("/", gin.BasicAuth(gin.Accounts{
     "dumbuser": "dumbuserpassword",
  }))
  authorized.POST("/events", events)
  router.Run(":8080")
}

func events(c *gin.Context) {
  fmt.Printf("%s", c.Request.Body)
  c.JSON(http.StatusOK, c)
}

答案1

得分: 32

问题在于你打印了c.Request.Body的字符串值,而它是一个接口类型ReadCloser

为了确保它确实包含你想要的请求体,你可以将c.Request.Body的值读取为字符串,然后打印出来。这只是为了你的学习过程!

学习代码:

func events(c *gin.Context) {
    x, _ := ioutil.ReadAll(c.Request.Body)
    fmt.Printf("%s", string(x))
    c.JSON(http.StatusOK, c)
}

然而,这不是你应该访问请求体的方式。让 Gin 通过使用绑定来解析请求体,这样更正确。

更正确的代码:

type E struct {
    Events string
}

func events(c *gin.Context) {
    data := &E{}
    c.Bind(data)
    fmt.Println(data)
    c.JSON(http.StatusOK, c)
}

这是一种更正确的访问请求体数据的方式,因为它已经被解析出来了。请注意,如果你首先读取了请求体,就像我们在学习步骤中所做的那样,c.Request.Body将会被清空,因此在请求体中将没有任何内容供 Gin 读取。

错误的代码:

func events(c *gin.Context) {
    x, _ := ioutil.ReadAll(c.Request.Body)
    fmt.Printf("%s", string(x))
    data := &E{}
    c.Bind(data) // data 不会被修改,因为 c.Request.Body 已经被使用完了。
    fmt.Println(data)
    c.JSON(http.StatusOK, c)
}

你可能还好奇为什么从这个端点返回的 JSON 显示一个空的Request.Body。原因是一样的。JSON 序列化方法无法序列化ReadCloser,所以它显示为空。

英文:

The problem here is that you're printing out the string value of c.Request.Body, which is of interface type ReadCloser.

What you can do to satisfy yourself that it does in fact contain the body you want is to read the value out of c.Request.Body to a string, and then print that out. This is for your learning process only!

Learning code:

func events(c *gin.Context) {
        x, _ := ioutil.ReadAll(c.Request.Body)
        fmt.Printf("%s", string(x))
        c.JSON(http.StatusOK, c)
}

However, this is not the way you should access the body of the request. Let gin do the parsing of the body for you, by using a binding.

More correct code:

type E struct {
        Events string
}

func events(c *gin.Context) {
        data := &E{}
        c.Bind(data)
        fmt.Println(data)
        c.JSON(http.StatusOK, c)
}

This is a more correct way to access the data in the body, since it will be already parsed out for you. Note that if you read the body first, as we did above in the learning step, the c.Request.Body will have been emptied, and so there will be nothing left in the body for Gin to read.

Broken code:

func events(c *gin.Context) {
	x, _ := ioutil.ReadAll(c.Request.Body)
	fmt.Printf("%s", string(x))
    data := &E{}
    c.Bind(data) // data is left unchanged because c.Request.Body has been used up.
    fmt.Println(data)
    c.JSON(http.StatusOK, c)
}

You're probably also curious why the JSON returned from this endpoint shows and empty Request.Body. This is for the same reason. The JSON Marshalling method cannot serialize a ReadCloser, and so it shows up as empty.

huangapple
  • 本文由 发表于 2015年8月10日 12:20:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/31911579.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定