代码之家  ›  专栏  ›  技术社区  ›  jaxxstorm

高栏的结构排列混乱

go
  •  1
  • jaxxstorm  · 技术社区  · 6 年前

    我正在尝试与JSON API交互。它有两个端点:

    GetTravelTimeAsJSON-指定traveltime ID并返回单个traveltime getTravelTimesJSON-返回包含以上所有旅行时间的数组。

    所以我有一个这样的结构:

    type TravelTime struct {
      AverageTime int     `json:"AverageTime"`
      CurrentTime int     `json:"CurrentTime"`
      Description string  `json:"Description"`
      Distance    float64 `json:"Distance"`
      EndPoint    struct {
        Description string  `json:"Description"`
        Direction   string  `json:"Direction"`
        Latitude    float64 `json:"Latitude"`
        Longitude   float64 `json:"Longitude"`
        MilePost    float64 `json:"MilePost"`
        RoadName    string  `json:"RoadName"`
      } `json:"EndPoint"`
      Name       string `json:"Name"`
      StartPoint struct {
        Description string  `json:"Description"`
        Direction   string  `json:"Direction"`
        Latitude    float64 `json:"Latitude"`
        Longitude   float64 `json:"Longitude"`
        MilePost    float64 `json:"MilePost"`
        RoadName    string  `json:"RoadName"`
      } `json:"StartPoint"`
      TimeUpdated  string `json:"TimeUpdated"`
      TravelTimeID int    `json:"TravelTimeID"`
    }
    

    如果我像这样调用API一次,我会得到一个填充的结构(我正在使用 this req lib )

    header := req.Header{
        "Accept":          "application/json",
        "Accept-Encoding": "gzip",
      }
      r, _ := req.Get("http://www.wsdot.com/Traffic/api/TravelTimes/TravelTimesREST.svc/GetTravelTimeAsJson?AccessCode=<redacted>&TravelTimeID=403", header)
      var foo TravelTime
    
      r.ToJSON(&foo)
      dump.Dump(foo)
    

    如果我转储响应,则如下所示:

    TravelTime {
      AverageTime: 14 (int),
      CurrentTime: 14 (int),
      Description: "SB I-5 Pierce King County Line To SR 512",
      Distance: 12.06 (float64),
      EndPoint:  {
        Description: "I-5 @ SR 512 in Lakewood",
        Direction: "S",
        Latitude: 47.16158351 (float64),
        Longitude: -122.481133 (float64),
        MilePost: 127.35 (float64),
        RoadName: "I-5"
      },
      Name: "SB I-5, PKCL To SR 512",
      StartPoint:  {
        Description: "I-5 @ Pierce King County Line",
        Direction: "S",
        Latitude: 47.255624 (float64),
        Longitude: -122.33113 (float64),
        MilePost: 139.41 (float64),
        RoadName: "I-5"
      },
      TimeUpdated: "/Date(1532707200000-0700)/",
      TravelTimeID: 403 (int)
    }
    

    现在,我要做的是为所有响应创建一个struct,它是 TravelTime struct,所以我这么做了:

    type TravelTimesResponse struct {
      TravelTime []TravelTime
    }
    

    但是,当我打电话给 GetTravelTimesAsJSON 端点,并将其更改为:

    var foo TravelTimesResponse
    

    我得到180个(结果数)空集,如下所示:

    {
        TravelTime: TravelTime {
          AverageTime: 0 (int),
          CurrentTime: 0 (int),
          Description: "",
          Distance: 0 (float64),
          EndPoint:  {
            Description: "",
            Direction: "",
            Latitude: 0 (float64),
            Longitude: 0 (float64),
            MilePost: 0 (float64),
            RoadName: ""
          },
          Name: "",
          StartPoint:  {
            Description: "",
            Direction: "",
            Latitude: 0 (float64),
            Longitude: 0 (float64),
            MilePost: 0 (float64),
            RoadName: ""
          },
          TimeUpdated: "",
          TravelTimeID: 0 (int)
        }
    

    JSON在这里: https://gist.github.com/jaxxstorm/0ab818b300f65cf3a46cc01dbc35bf60

    如果我修改原始的 旅行时间 构造成这样的切片:

    type TravelTimes []struct {
    
    }
    

    但这不是一个单一的反应。

    我以前也试过,但由于某种原因,这次失败的原因是我的大脑出了问题。感谢任何帮助。

    2 回复  |  直到 6 年前
        1
  •  -1
  •   Himanshu    6 年前

    更改结构 TravelTimesResponse 字段名 TravelTime 类似于 struct 名称 旅行时间 然后尝试解开JSON。

    type TravelTimesResponse struct {
      TravelTime []TravelTime
    }
    

    上面应该有不同的字段名:

    type TravelTimesResponse struct {
      TravelTimeData []TravelTime
    }
    

    [编辑]

    这个 library 正在使用 interface{} 直接解组响应

    // ToJSON convert json response body to struct or map
    func (r *Resp) ToJSON(v interface{}) error {
        data, err := r.ToBytes()
        if err != nil {
            return err
        }
        return json.Unmarshal(data, v)
    }
    

    给定的JSON是一个对象数组。 您正在将其解析为具有字段名的结构,该字段名将是对象键。创建一个struct片段或实现解组。

    Unmarshal 将其中一个存储在接口值中:

    bool, for JSON booleans
    float64, for JSON numbers
    string, for JSON strings
    []interface{}, for JSON arrays
    map[string]interface{}, for JSON objects
    nil for JSON null
    

    最好是用围棋包 encoding/json .

    尝试使用代码 Go playground

        2
  •  2
  •   Adrian    6 年前

    解组不起作用,因为它希望顶层是一个带有字段的对象 TravelTime ,当顶层实际上是对象数组时。你只想把它直接分解成一片物体,就像这样:

      var foo []TravelTime
    
      r.ToJSON(&foo)