英文:
I cannot get posted body in revel go framework
问题
我正在尝试在revel中使用Rest架构实现基本的CRUD操作,但是我无法将以json
格式编码的数据发送到一个端点。我尝试了多种方法来检查请求中的请求体内容,所以现在我有一个"最小可编译示例":
-
使用revel cli工具创建一个新项目。
-
应用以下更改:
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
- 发送一个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":
-
create a new project using revel cli tool.
-
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
-
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/json
或text/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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论