英文:
Chi empty http.Request.Body in render.Bind
问题
我正在使用github.com/pressly/chi构建这个简单的程序,我尝试从http.Request.Body
解码一些JSON:
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/pressly/chi"
"github.com/pressly/chi/render"
)
type Test struct {
Name string `json:"name"`
}
func (p *Test) Bind(r *http.Request) error {
err := json.NewDecoder(r.Body).Decode(p)
if err != nil {
return err
}
return nil
}
func main() {
r := chi.NewRouter()
r.Post("/products", func(w http.ResponseWriter, r *http.Request) {
var p Test
// err := render.Bind(r, &p)
err := json.NewDecoder(r.Body).Decode(&p)
if err != nil {
panic(err)
}
fmt.Println(p)
})
http.ListenAndServe(":8080", r)
}
当我不使用render.Bind()
(来自"github.com/pressly/chi/render"
)时,它按预期工作。
然而,当我取消注释err := render.Bind(r, &p)
这一行,并注释掉err := json.NewDecoder(r.Body).Decode(&p)
这一行时,它会出现EOF
的panic错误:
2017/06/20 22:26:39 http: panic serving 127.0.0.1:39696: EOF
因此,json.Decode()
失败了。
我是否做错了什么,或者在调用render.Bind()
之前,http.Request.Body
已经在其他地方被读取了?
英文:
I am using github.com/pressly/chi to build this simple program where I try to decode some JSON from the http.Request.Body
:
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/pressly/chi"
"github.com/pressly/chi/render"
)
type Test struct {
Name string `json:"name"`
}
func (p *Test) Bind(r *http.Request) error {
err := json.NewDecoder(r.Body).Decode(p)
if err != nil {
return err
}
return nil
}
func main() {
r := chi.NewRouter()
r.Post("/products", func(w http.ResponseWriter, r *http.Request) {
var p Test
// err := render.Bind(r, &p)
err := json.NewDecoder(r.Body).Decode(&p)
if err != nil {
panic(err)
}
fmt.Println(p)
})
http.ListenAndServe(":8080", r)
}
When I don't use render.Bind()
(from "github.com/pressly/chi/render"
), it works as expected.
However, when I uncomment the line err := render.Bind(r, &p)
and I comment the line err := json.NewDecoder(r.Body).Decode(&p)
, it panics with EOF
:
> 2017/06/20 22:26:39 http: panic serving 127.0.0.1:39696: EOF
and thus the json.Decode()
fails.
Am I doing something wrong or is the http.Request.Body
is already read somewhere else before render.Bind()
is called?
答案1
得分: 4
render.Bind的目的是执行解码并执行Bind(r)
以进行解码后的操作。
例如:
type Test struct {
Name string `json:"name"`
}
func (p *Test) Bind(r *http.Request) error {
// 此时,`chi`已经完成了解码
p.Name = p.Name + " after decode"
return nil
}
如果您只需要进行JSON解码,而不需要对解码后的值进行其他操作,请使用以下方法之一:
// 使用标准包的JSON解码器
err := json.NewDecoder(r.Body).Decode(&p)
或者
// 使用chi的DecodeJSON包装方法
err := render.DecodeJSON(r.Body, &p)
英文:
render.Bind's purpose is to perform decode and execute Bind(r)
to do post decode operations.
For eg.:
type Test struct {
Name string `json:"name"`
}
func (p *Test) Bind(r *http.Request) error {
// At this point, Decode is already done by `chi`
p.Name = p.Name + " after decode"
return nil
}
If you have to do only JSON decode no other actions needs to be done after decode with respect to decoded values. Just use:
// Use Directly JSON decoder of std pkg
err := json.NewDecoder(r.Body).Decode(&p)
OR
// Use wrapper method from chi DecodeJSON
err := render.DecodeJSON(r.Body, &p)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论