英文:
How to JSON-decode lowercased names into my struct?
问题
我开始为了让Go解码这个JSON请求体而变得疯狂。这是一个示例请求:
curl -X POST -d "{\"username\":\"foo\", \"password\":\"bar\"}" http://localhost:3000/users
这是我的处理程序:
mux.HandleFunc("/users", func(rw http.ResponseWriter, req *http.Request) {
var body struct {
username string
password string
}
// buf := make([]byte, req.ContentLength)
// req.Body.Read(buf)
// fmt.Println(string(buf))
//
// 上面被注释掉的代码将正确打印:
// {"username":"foo", "password":"bar"}
err := json.NewDecoder(req.Body).Decode(&body)
if err != nil {
rw.WriteHeader(http.StatusNotAcceptable)
return
}
fmt.Printf("%+v\n", body)
// 输出 -> {username: password:}
})
如同注释所示,我可以验证req.Body
是正确的--但是出于某种原因,json.NewDecoder(req.Body).Decode(&body)
从不填充body
的字段。
非常感谢任何帮助!
英文:
I'm starting to go crazy trying to get Go to decode this json request body. Here's a sample request:
curl -X POST -d "{\"username\":\"foo\", \"password\":\"bar\"}" http://localhost:3000/users
And here's my handler:
mux.HandleFunc("/users", func(rw http.ResponseWriter, req *http.Request) {
var body struct {
username string
password string
}
// buf := make([]byte, req.ContentLength)
// req.Body.Read(buf)
// fmt.Println(string(buf))
//
// The above commented out code will correctly print:
// {"username":"foo", "password":"bar"}
err := json.NewDecoder(req.Body).Decode(&body)
if err != nil {
rw.WriteHeader(http.StatusNotAcceptable)
return
}
fmt.Printf("%+v\n", body)
// prints -> {username: password:}
})
Like the comment suggests, I can verify that req.Body
is indeed correct -- but for whatever reason, json.NewDecoder(req.Body).Decode(&body)
never fills out the fields of body
.
Any help would be greatly appreciated!
答案1
得分: 5
问题在于JSON解码器无法处理私有结构字段。您的body
结构中的字段是私有的。
将其重写如下,它将正常工作:
var body struct {
Username string `json:"username"`
Password string `json:"password"`
}
基本上,json:"username"
是一种告诉JSON解码器如何将JSON对象的名称映射到结构名称的方法。在这种情况下,仅用于解码,它是不必要的 - JSON解码器足够聪明,可以进行大小写的转换。
但是,如果您还要使用该对象来编码JSON,那么您就需要它,否则在生成的JSON中将有大写字段名。
您可以使用JSON结构标签进行更多有用的操作,例如从编码的JSON中省略空字段或完全跳过字段。
您可以在json.Marshal
的文档中阅读有关JSON结构标签的更多信息:http://golang.org/pkg/encoding/json/#Marshal
英文:
The problem is that the json decoder does not deal with private struct fields. The fields in your body
structs are private.
Rewrite it like so and it will work:
var body struct {
Username string `json:"username"`
Password string `json:"password"`
}
basically the json:"username"
is a way to tell the json decoder how to map the json name of the object to the struct name. In this instance, for decoding only, it is not necessary - the json decoder is smart enough to make the translation of the upper/lower case.
But if you use the object to encode json as well, you need it, or you'll have upper case field names in the resulting json.
You can use the json struct tags for a few more useful things, like omitting empty field from encoded json, or skipping fields entirely.
You can read more about the JSON struct tags in the documentation for json.Marshal
: http://golang.org/pkg/encoding/json/#Marshal
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论