做 json.取消封送要求结果结构与传入的 JSON 完全匹配

  • 本文关键字:JSON 结构 取消 json 结果 json go
  • 更新时间 :
  • 英文 :


我有一个想要解组的 JSON 字符串:

{
  "id":1720,
  "alertId":1,
  "alertName":"{stats} Test Lambda Alert",
  "dashboardId":5,
  "panelId":2,
  "userId":0,
  "newState":"alerting",
  "prevState":"ok",
  "time":1523983581000,
  "text":"",
  "regionId":0,
  "tags":[],
  "login":"",
  "email":"",
  "avatarUrl":"",
  "data":{
    "evalMatches":[
        {
         "metric":"{prod}{stats} Lambda Alert Test",
         "tags":null,
         "value":16.525333333333332
         }
     ]
   }
}

我通过请求获取原始流:bodyBytes, err := ioutil.ReadAll(resp.Body)

我希望我能指定一个结构来拉动我关心的值,例如,

type Result struct {
    ID string `json:"id"`
    Time int64 `json:"time"`
}

但是,当我尝试此操作时,我会收到错误。

type Result struct {
    ID   string `json:"id"`
    Time string `json:"time"`
}
var result Result
err2 := json.Unmarshal(bodyBytes, &result)
if err2 != nil {
    log.Fatal(fmt.Sprintf(`Error Unmarshalling: %s`, err2))
}
fmt.Println(result.ID)

错误解组: json:无法将数组解组为 main 类型的 Go 值。结果

我怀疑此错误可能是由于实际从ioutil.ReadAll()返回的内容,因为如果我执行fmt.Println(string(bodyBytes)),它将上述 JSON 字符串包装在[ ]中,但如果我尝试json.Unmarshal(bodyBytes[0], &result),我只是得到编译错误,所以我不确定。

如果我想取消封送 JSON 字符串,我是否必须在type Result struct中指定完整的结构?有没有办法解决这个问题?我不想绑定到我收到的 JSON 对象(如果 API 在上游发生变化,它需要我们修改代码以识别它,等等(。

您可以取消编组为仅表示 JSON 文档的某些字段的结构,但字段类型必须匹配,如错误明确指出的那样:

无法将数字解编到字符串类型的 Go 结构字段 Result.id 中

不能将数字取消封送为字符串。如果将 ID 字段定义为任何数字类型,它将正常工作:

package main
import (
    "encoding/json"
    "fmt"
)
var j = []byte(`
{
  "id":1720,
  "prevState":"ok",
  "time":1523983581000,
  "text":"",
  "regionId":0
}
`)
type Result struct {
    ID   int   `json:"id"` // or any other integer type, or float{32,64}, or json.Number
    Time int64 `json:"time"`
}
func main() {
    var r Result
    err := json.Unmarshal(j, &r)
    fmt.Println(r, err)
}

在操场上尝试一下:https://play.golang.org/p/lqsQwLW2dHZ

更新

您刚刚使用收到的实际错误编辑了问题。您必须将 JSON 数组解编为切片。因此,如果 HTTP 响应实际上返回了一个 JSON 数组,请取消编组到 []Result:

var j = []byte(`
[
    {
      "id":1720,
      "prevState":"ok",
      "time":1523983581000,
      "text":"",
      "regionId":0
    }
]
`)
var r []Result
err := json.Unmarshal(j, &r)
fmt.Println(r[0], err)

https://play.golang.org/p/EbOVA8CbcFO

要生成与您的 JSON 文档非常匹配的 Go 类型,请使用 https://mholt.github.io/json-to-go/。

最新更新