我是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)
}
答案 0 :(得分:24)
这里的问题是你打印出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)
}
但是,这不是您应该访问请求正文的方式。让杜松子酒通过使用绑定来为你解析身体。
更正确的代码:
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 is left unchanged because c.Request.Body has been used up.
fmt.Println(data)
c.JSON(http.StatusOK, c)
}
您可能也很好奇为什么从此端点返回的JSON显示并清空Request.Body
。出于同样的原因。 JSON编组方法无法序列化ReadCloser
,因此显示为空。