1. 概述
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。key-val
JSON是在2001年开始推广使用的数据格式,目前已经称为主流的数据格式。
JSON易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络传输时会先将数据(结构体、map等)序列化成JSON字符串,到接收方得到JSON字符串时,再反序列化恢复成原来的数据类型(结构体、map等)。这种方式已然成为各个语言的标准。
2. 应用场景(示意图)
3. JSON数据格式说明
4. JSON数据在线解析
https://www.json.cn/ 网站可以验证一个json格式的数据是否正确。尤其在我们编写比较复杂的格式数据时,很有用。
5. JSON的序列化
1)介绍
JSON序列化是指,将有key-value结构的数据类型(比如结构体、map、切片)序列化成JSON字符串的操作。
2)应用案例
这里我们介绍一下结构体、map和切片的序列化,其它数据类型的序列化类似。
代码演示:
package main
import (
"fmt"
"encoding/json"
)
// 定义一个结构体
type Monster struct {
Name string
Age int
Birthday string
Sal float64
Skill string
}
// 将struct序列化
func testStruct () {
// 演示
monster := Monster{
Name: "牛魔王",
Age: 500,
Birthday: "2011-11-11",
Sal: 8000.0,
Skill: "牛魔拳",
}
// 将monster序列化
data, err := json.Marshal(&monster)
if err != nil {
fmt.Printf("序列化错误,err=%v\n",err)
}
// 输出序列化后的结果
fmt.Printf("monster 序列化后的结果=%v\n",string(data))
}
// 将map序列化
func testMap() {
// 定义一个map
var a map[string]interface{}
// 使用map,需要make
a = make(map[string]interface{})
a["name"] = "红孩儿"
a["age"] = 30
a["address"] = "洪崖洞"
// 将a这个map进行序列化
data, err := json.Marshal(a)
if err != nil {
fmt.Printf("序列化错误,err=%v\n",err)
}
fmt.Printf("map 序列化后的结果=%v\n",string(data))
}
// 演示对切片的序列化,我们这个切片[]map[string]interface{}
func testSlice() {
var slice []map[string]interface{}
var m1 map[string]interface{}
// 使用map前,需要先make
m1 = make(map[string]interface{})
m1["name"] = "jack"
m1["age"] = 100
m1["address"] = "北京天安门"
slice = append(slice,m1)
var m2 map[string]interface{}
// 使用map前,需要先make
m2 = make(map[string]interface{})
m2["name"] = "tom"
m2["age"] = 20
m2["address"] = [2]string{"墨西哥","夏威夷"}
slice = append(slice, m2)
// 将切片进行序列化
data, err := json.Marshal(slice)
if err != nil {
fmt.Println("切片序列化错误,err=",err)
}
fmt.Printf("slice 序列化后=%v",string(data))
}
// 对基本数据类型序列化,对基本数据类型进行序列化意义不大
func testFloat64() {
var num1 float64 = 23456.789
// 对num1进行序列化
data, err := json.Marshal(num1)
if err != nil {
fmt.Println("float64 序列化错误, err=",err)
}
// 输出序列化后的结果
fmt.Println("float64 序列化后=%v\n",string(data))
}
func main() {
testStruct()
testMap()
testSlice()
testFloat64()
}
注意事项:
对于结构体的序列化,如果我们希望序列化后的key的名字,由我们自己重新指定,那么可以给struct指定一个tag标签
序列化后:
6. JSON的反序列化
1)基本介绍
JSON反序列化是指,将JSON字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作
2)应用案例
这里我们介绍一下将JSON字符串反序列化成结构体、map和切片
代码演示:
package main
import (
"fmt"
"encoding/json"
)
// 定义一个结构体
type Monster struct {
Name string
Age int
Birthday string
Sal float64
Skill string
}
// 演示将JSON字符串,反序列化成struct
func unmarshalStruct() {
// 说明 str在项目开发中,是通过网络传输获取到... 或是读取文件获取到
str := "{\"Name\":\"孙悟空\",\"Age\": 500,\"Birthday\":\"2021-08-18\",\"Sal\":8000,\"Skill\":\"三昧真火\"}"
// 定义一个Monster实例
var monster Monster
err := json.Unmarshal([]byte(str),&monster)
if err != nil {
fmt.Printf("unmarsha err=%v",err)
}
fmt.Printf("反序列化后 monster=%v monster.Name=%v\n",monster,monster.Name)
}
// 演示将JSON字符串,反序列化成map
func unmarshalMap() {
str := "{\"address\":\"北京天安门\",\"age\":30,\"name\":\"奥特曼\"}"
// 定义一个map
var a map[string]interface{}
// 反序列化
// 注意:反序列化 map,不需要make,因为make操作被封装到Unmarshal函数
err := json.Unmarshal([]byte(str),&a)
if err != nil {
fmt.Println("map 反序列化失败, err=",err)
}
fmt.Printf("反序列化后 a=%v\n",a)
}
// 演示将JSON字符串,反序列化成切片
func unmarshalSlice() {
str := "[{\"address\":\"北京天安门\",\"age\":30,\"name\":\"李白\"},{\"address\":[\"南昌\",\"马六甲海峡\"],\"age\":30,\"name\":\"李白\"}]"
// 定义一个slice
var slice []map[string]interface{}
// 反序列化,不需要make,因为make操作被封装到了Unmarshal函数
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Println("slice 反序列化失败, err=",err)
}
fmt.Println("反序列化后=",slice)
}
func main() {
unmarshalStruct()
unmarshalMap()
unmarshalSlice()
}
对上面代码的小结说明:
1)在反序列化一个JSON字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。
2)如果JSON字符串是通过程序获取到的,则不需要再对"进行转义处理。