dream543211
2018-07-17 15:47
浏览 162

Go中的嵌套JSON反序列化

I am attempting to convert a nested JSON response to a struct. The struct looks as follows:

type PullRequestEvent struct {
    Action               string   `json:"action"`
    Number               int      `json:"number"`
    PullRequest          struct { 
        Url              string   `json:"url"`
        HtmlUrl          string   `json:"html_url"`
        DiffUrl          string   `json:"diff_url"` 
        Title            string   `json:"title_url"` 
    } `json:"pull_request"`
}

However, only the top-level fields (Action,Number) are being parsed; the rest remain nil or 0. The conversion code is as follows:

func whatever(w http.ResponseWriter, r *http.Request) {
    var ev PullRequestEvent
    dec := json.NewDecoder(r.Body)
    err := dec.Decode(&ev)
    if err != nil {
        // fail request 
    }
}

The JSON is the pull request event here. The relevant parts are

{   
    "action": "closed",   "number": 1,   "pull_request": {
    "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1",
    "id": 191568743,
    "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz",
    "html_url": "https://github.com/Codertocat/Hello-World/pull/1",
    "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff",
    "number": 1,
    "state": "closed",
    "locked": false,
    "title": "Update the README with new information",
    "user": {
      "login": "Codertocat",
      "id": 21031067,
      "node_id": "MDQ6VXNlcjIxMDMxMDY3",
      "gravatar_id": "",
      "url": "https://api.github.com/users/Codertocat",
      "html_url": "https://github.com/Codertocat",
      "subscriptions_url": "link",
      "organizations_url": "link",
      "repos_url": "link",
      "events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
      "received_events_url": "link",
      "type": "User",
      "site_admin": false
    }
    //...  }

What is wrong with the code here?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dsam70528 2018-07-17 16:19
    已采纳

    There's no issue with the code you posted, except that there is no field title_url in the response you expect (you probably wanted just title). Here's a playground example that showcases it.

    package main
    
    import (
        "bytes"
        "encoding/json"
        "log"
    )
    
    const examplePayload = `
    {
      "action": "closed",
      "number": 1,
      "pull_request": {
        "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1",
        "id": 191568743,
        "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz",
        "html_url": "https://github.com/Codertocat/Hello-World/pull/1",
        "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff",
        "patch_url": "https://github.com/Codertocat/Hello-World/pull/1.patch",
        "issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1",
        "number": 1,
        "state": "closed",
        "locked": false,
        "title": "Update the README with new information"
      }
    }
    `
    
    type PullRequestEvent struct {
        Action      string `json:"action"`
        Number      int    `json:"number"`
        PullRequest struct {
            Url     string `json:"url"`
            HtmlUrl string `json:"html_url"`
            DiffUrl string `json:"diff_url"`
            Title   string `json:"title"`
        } `json:"pull_request"`
    }
    
    func main() {
      var ev PullRequestEvent
        ex := bytes.NewReader([]byte(examplePayload))
        if err := json.NewDecoder(ex).Decode(&ev); err != nil {
            log.Fatal(err)
        }
        log.Printf("%#v", ev)
    }
    
    点赞 评论

相关推荐 更多相似问题