簡體   English   中英

Unmarshal只給了我嵌套在JSON響應中的數組的第一個元素

[英]Unmarshal only gives me first element of array that is nested in JSON response

我正在嘗試使用Flickr API,並且有一個端點可以給我這樣的響應

{
  "photos": {
    "page": 1,
    "pages": 500,
    "perpage": 1,
    "total": 500,
    "photo": [
      {
        "id": "12345",
        "owner": "12345@N01",
        "secret": "12ab345xyz",
        "server": "1234",
        "farm": 1,
        "title": "Some Title",
        "ispublic": 1,
        "isfriend": 0,
        "isfamily": 0
      },
     ...
    ]
  },
  "stat": "ok"
}

我有一個看起來像這樣的結構

type FlickrResp struct {
    Photos struct {
        Page int            `json:"page"`       //what page the results were retreived from
        Pages int           `json:"pages"`      //total number of pages of results
        Perpage int         `json:"perpage"`    //number of results per page
        Total int           `json:"total"`      //total number of results
        Photo []struct {
            ID string       `json:"id"`         //image ID
            Owner string    `json:"owner"`      //owner ID
            Secret string   `json:"secret"`     //owner secret
            Server string   `json:"server"`     //server ID
            Farm int        `json:"farm"`       //farm ID
            Title string    `json:"title"`      //image title
            Ispublic string `json:"ispublic"`   //is image publicly viewable?
            Isfriend string `json:"isfriend"`   //is image owner my friend?
            Isfamily string `json:"isfamily"`   //is image owner my family?
        }                   `json:"photo"`      //array of objects with details of photos
    }                       `json:"photos"`     //object that holds information about photoset
    Stat string             `json:"stat"`       //status
}

我正試圖解組

var fr FlickrResp                                               //create blank struct of type FlickrResp to hold JSON
resp, err := ioutil.ReadAll(flickrCB.Body)                      //read HTTP GET response
if err != nil {

}
json.Unmarshal([]byte(resp), &fr)                               //serialize JSON into template

flickCB.Body來自http.Get

問題是我只得到照片陣列的第一個元素。 當我將響應對象轉換為字符串打印時,可以看到有多個元素。 我究竟做錯了什么? 幾天來,我一直在反對Unmarshal和更復雜的JSON響應。

最初在評論中回答,但有一點澄清:

json.Unmarshal有一個未捕獲的錯誤:

json: cannot unmarshal number into Go value of type string

由閃爍API提供整數形式的ispublicisfriendisfamily API之間的類型不匹配引起,但該結構期望字符串。 一個簡單的解決方法是將它們轉換為整數。

這些情況的另一種選擇是使用json.Number ,它包裝了源json中的基本字符串,並提供了一些方便的方法來稍后將其轉換為數字(或只是將其保留為字符串)。 通過說

Ispublic json.Number `json:"ispublic"`   //is image publicly viewable?
Isfriend json.Number `json:"isfriend"`   //is image owner my friend?
Isfamily json.Number `json:"isfamily"`

它將正常工作,並且可以通過fr.Ispublic.String()輕松將結果作為字符串fr.Ispublic.String()

在這種情況下可能更有用的更精細的更改是使用自定義布爾類型。 有問題的值似乎反映了布爾值,但是整數也不能干凈地映射到布爾值。 可以使用自定義反序列化類型。 從此示例借用stackoverflow的其他地方:

type ConvertibleBoolean bool

func (bit ConvertibleBoolean) UnmarshalJSON(data []byte) error {
    asString := string(data)
    if asString == "1" || asString == "true" {
        bit = true
    } else if asString == "0" || asString == "false" {
        bit = false
    } else {
        return errors.New(fmt.Sprintf("Boolean unmarshal error: invalid input %s", asString))
    }
    return nil
}

上面的代碼使您可以將Is*值聲明為ConvertibleBoolean ,並將自動將在Flickr到布爾值的那些字段中獲得的0和1值自動映射。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM