如何将小写名称解码为我的结构体中的 JSON 数据?

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

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

huangapple
  • 本文由 发表于 2015年2月21日 18:14:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/28644600.html
匿名

发表评论

匿名网友

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

确定