我想要解组的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.Result的Go值
我怀疑这个错误可能是由ioutil.ReadAll()
实际返回的内容造成的,因为如果我执行[ ]
,它会在fmt.Println(string(bodyBytes))
中包含上面的JSON字符串,但如果我尝试json.Unmarshal(bodyBytes[0], &result)
,我只是遇到编译错误,所以我不确定。
如果我要解组JSON字符串,是否必须在type Result struct
中指定完整结构?有没有解决的办法?我不想被绑定到我收到的JSON对象(如果API在上游发生变化,它需要我们修改我们的代码以识别它等)。
答案 0 :(得分:3)
您可以解组为仅表示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/。