json Unmarshal时实际字段类型与struct定义不一致会影响其他正常字段解析

json Unmarshal时实际字段类型与struct定义不一致会影响其他正常字段解析?
见代码


package main

import (
"encoding/json"
"fmt"
)

type Role struct {
Attr struct {
Lv int64 `json:"lv"`
Money int64 `json:"money"`
} `json:"attr"`
Net struct {
Ip string `json:"ip"`
Mac string `json:"mac"`
} `json:"net"`
}

func main() {
str := `{"attr":{"lv":15,"money":3},"net":{"ip":"8.8.8.8","mac":0}}`
str2 := `{"net":{"ip":"8.8.8.8","mac":0},"attr":{"lv":15,"money":3}}`
logData := &Role{}
logData2 := &Role{}
err := json.Unmarshal([]byte(str), logData)
err2 := json.Unmarshal([]byte(str2), logData2)

fmt.Printf("%#v\r\n", logData)
fmt.Println(logData)
fmt.Println(err)

fmt.Printf("%#v\r\n", logData2)
fmt.Println(logData2)
fmt.Println(err2)
}

输出结果是


&main.Role{Attr:struct { Lv int64 "json:\"lv\""; Money int64 "json:\"money\"" }{Lv:15, Money:3}, Net:struct { Ip string "json:\"ip\""; Mac string "json:\"mac\"" }{Ip:"8.8.8.8", Mac:""}}
&{{15 3} {8.8.8.8 }}
json: cannot unmarshal number into Go struct field .mac of type string

&main.Role{Attr:struct { Lv int64 "json:\"lv\""; Money int64 "json:\"money\"" }{Lv:0, Money:0}, Net:struct { Ip string "json:\"ip\""; Mac string "json:\"mac\"" }{Ip:"8.8.8.8", Mac:""}}
&{{0 0} {8.8.8.8 }}
json: cannot unmarshal number into Go struct field .mac of type string

可以看到,struct的mac是string类型的,实际的json字符串中mac因为一些不可控的原因等于int 0
测试中发现解析发生错误后,后面的所有key都无法解析了,但是在实际项目中,json产出数据不可控,是否有办法跳过错误继续处理呢


测试地址

已邀请:

iron_js

赞同来自: hechen

1,尝试过使用一个字段专门表示那些不可控的key,由对方传,解析的时候使用JSON.RawMessage逐层解析,拿到key,再按照json.unmashal解析
2,可以使用map[string]interface{}解析,但是最后要把interface{}映射成struct比较费劲

wulinlw

赞同来自: Anjie

好了,自己解决了
准备用github.com/json-iterator/go 处理的,但是测试后还是没有办法满足千变万化的日志,没有办法啊
修改了官方go 1.8.3 "encoding/json"包的json.Unmarshal(),几乎不会影响性能吧
兼容了string和int64,现在struct的定义不管是string还是int64,json字符串中的值随便搞也不会出错了
https://github.com/wulinlw/jsonAmbiguity

skylzyd - 程序员

赞同来自:

改成interface{},用到该字段的时候再类型断言

tom0001

赞同来自:

json包有一个方法是'json:"mac,string"'

要回复问题请先登录注册