使用Go语言解析动态JSON格式的方法

2020-01-28 12:54:36于丽

    § JSON中的布尔值将会转换为Go中的bool类型 § 数值会被转换为Go中的float64类型 § 字符串转换后还是string类型 § JSON数组会转换为[]interface{} 类型 § JSON对象会转换为map[string]interface{}类型 § null值会转换为nil

注意:在Go的标准库encoding/json包中,允许使用map[string]interface{}和[]interface{} 类型的值来分别存放未知结构的JSON对象或数组

1、传统方法

比如 User 数据结构如下:


type User struct {
 Name string `json:"name"`
 Age int  `json:"age"`
}

在定义struct字段的时候,可以在字段后面添加tag,来控制encode/decode的过程:是否要 decode/encode 某个字段,JSON 中的字段名称是什么。字段名首字母控制字段的可见性,若要输出到JSON,首字母需要大写。

三种tag:

- :不要解析这个字段

omitempty :当字段为空(默认值)时,不要解析这个字段。比如 false、0、nil、长度为 0 的 array,map,slice,string

FieldName :当解析 json 的时候,使用这个名字

举例来说吧:


// 解析的时候忽略该字段。默认情况下会解析这个字段,因为它是大写字母开头的
Field int `json:"-"`
// 解析(encode/decode) 的时候,使用 `other_name`,而不是 `Field`
Field int `json:"other_name"`
// 解析的时候使用 `other_name`,如果struct 中这个值为空,就忽略它
Field int `json:"other_name,omitempty"`

(1)encode


user := User{Name: "test", Age:23}
data, err := json.Marshal(user)
if err != nil {
 fmt.Println(string(data))
}

data 就是 []byte 类型的数组,里面包含了解析为 JSON 之后的数据,可以使用string(data)转型为string。

(2)decode

要把JSON数据转换成Go类型的值(Decode),可以使用 json.Unmarshal 。


var user User
err = json.Unmarshal(data, &user)
if err != nil {
 fmt.Errorf("Can not decode data: %vn", err)
}

2、动态解析

动态JSON结构未知,若使用前面方法需要事先定义数据结构,这与PHP/Python JSON处理非常不同。若不考虑性能,使用simplejson。

(1)simplejson


js, err := simplejson.NewJson([]byte(`{
 "test": {
  "string_array": ["asdf", "zxcv"],
  "array": [1, "2", 3],
  "arraywithsubs": [{"subkeyone": 1},
  "bignum": 9223372036854775807,
  "string": "simplejson",
  "bool": true
 }
 }`))
 if err != nil {
  panic("json format error")
 }
 //获取某个字段值
 s, err := js.Get("test").Get("string").String()
 if err != nil {
  panic(err)
 }
 fmt.Println(s)
 //检查某个字段是否存在
 _, ok := js.Get("test").CheckGet("string2")
 if ok {
  fmt.Println("存在!")
 } else {
  fmt.Println("不存在")
 }