我无法在Revel Go框架中获取发布的请求体。

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

I cannot get posted body in revel go framework

问题

我正在尝试在revel中使用Rest架构实现基本的CRUD操作,但是我无法将以json格式编码的数据发送到一个端点。我尝试了多种方法来检查请求中的请求体内容,所以现在我有一个"最小可编译示例":

  1. 使用revel cli工具创建一个新项目。

  2. 应用以下更改:

diff --git a/app/controllers/app.go b/app/controllers/app.go
index 1e94062..651dbec 100644
--- a/app/controllers/app.go
+++ b/app/controllers/app.go
@@ -9,5 +9,6 @@ type App struct {
 }
 
 func (c App) Index() revel.Result {
-	return c.Render()
+	defer c.Request.Body.Close()
+	return c.RenderJSON(c.Request.Body)
 }
diff --git a/conf/routes b/conf/routes
index 35e99fa..5d6d1d6 100644
--- a/conf/routes
+++ b/conf/routes
@@ -7,7 +7,7 @@ module:testrunner
 # module:jobs


-GET     /                                       App.Index
+POST     /                                       App.Index

# Ignore favicon requests
GET     /favicon.ico                            404
  1. 发送一个POST请求:
curl --request POST --header "Content-Type: application/json" --header "Accept: application/json" --data '{"name": "Revel framework"}' http://localhost:9000

我的问题是,curl调用没有给我返回回显(相同的json {"name": "Revel framework"}),所以我在正确使用revel方面漏掉了什么?

PS:我可以找到一些其他相关的链接来解决这个问题,但它们对我不起作用。例如,这个链接:https://github.com/revel/revel/issues/126

英文:

I am trying to implement a basic CRUD using the Rest architecture in revel, but I am not able to send the data encoded in json format to an endpoint, I was try multiple ways to check the body content in the request, so now I have a "minimal compilable example":

  1. create a new project using revel cli tool.

  2. Apply the following changes

     diff --git a/app/controllers/app.go b/app/controllers/app.go
     index 1e94062..651dbec 100644
     --- a/app/controllers/app.go
     +++ b/app/controllers/app.go
     @@ -9,5 +9,6 @@ type App struct {
      }
    
      func (c App) Index() revel.Result {
     -	return c.Render()
     +	defer c.Request.Body.Close()
     +	return c.RenderJSON(c.Request.Body)
      }
     diff --git a/conf/routes b/conf/routes
     index 35e99fa..5d6d1d6 100644
     --- a/conf/routes
     +++ b/conf/routes
     @@ -7,7 +7,7 @@ module:testrunner
      # module:jobs
    
    
     -GET     /                                       App.Index
     +POST     /                                       App.Index
    
      # Ignore favicon requests
      GET     /favicon.ico                            404
    
  3. do a POST request:

     curl --request POST --header "Content-Type: application/json" --header "Accept: application/json" --data '{"name": "Revel framework"}' http://localhost:9000
    

My problem; the curl call does not give me an echo back (the same json {"name": "Revel framework"}), so what I am missing to use revel correctly?

PS: I can find some other related links to this problem but they do not work for me. For example this: https://github.com/revel/revel/issues/126

答案1

得分: 5

根据Revel的源代码(https://github.com/revel/revel/blob/v0.17.1/params.go#L63),当请求的内容类型为application/jsontext/json时,请求体的内容会自动从流中读取并存储到c.Params.JSON中,c.Params.JSON的类型为[]byte

由于Request.Body是一个只能读取一次的流,所以你不能再次读取它(即使Revel不自动读取流,你的代码也无法正常工作,因为c.Request.Body不能正确地使用c.RenderJSON()进行序列化)。

Revel提供了一个方便的函数Params.BindJSON,它可以将c.Params.JSON转换为Go语言对象。

以下是示例代码:

type MyData struct {
    Name string `json:"name"`
}

func (c App) Index() revel.Result {
    data := MyData{}
    c.Params.BindJSON(&data)
    return c.RenderJSON(data)
}
英文:

According to the source of Revel, when the request content type is either application/json or text/json, the content of request body is automatically read from stream and stored to c.Params.JSON which has type []byte.

Since the Request.Body is a stream which can only be read once, you cannot read it again (and anyway, your code won't work even if Revel does not automatically read the stream, since c.Request.Body is not correctly serialiazable usingc.RenderJSON()).

Revel has convenient function Params.BindJSON which converts c.Params.JSON to the golang object.

Here's sample code.

type MyData struct {
	Name string `json:"name"`
}

func (c App) Index() revel.Result {
	data := MyData{}
	c.Params.BindJSON(&data)
	return c.RenderJSON(data)
}

huangapple
  • 本文由 发表于 2017年9月4日 07:41:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/46028723.html
匿名

发表评论

匿名网友

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

确定