json 简介
json是一种轻量级的网络数据交换格式,到2005开始,正式成为主流的数据格式。
json的应用,大到大名鼎鼎的谷歌公司,小到公司内部系统。
json特点
json易于程序解析和生成,并有效的提升网络传输效率,通常程序在网络传输时,会先将数据(golang中的结构体、map数据机构) 序列化 成json 字符串 (类似于文本),接收方收到json字符串并反序列化成原先数据类型(结构体、map等),这种方式得到广泛的认可并成为各种语言的标准。
golang解析json流程
json数据格式
在json语言中,一切皆对象,支持任何类型数据进行json格式转换,日历字符串、数字、对象、数组等等。
json以键值对(key-value)形式保存数据。例如:
{ "name":"zhangsan", "age" : 32 }
其中key以双引号””包裹,用冒号“:”分割,然后后面是具体值
在线json格式解析工具
json序列化
是指将键值对(key-value)结构的数据类型(结构体、map、切片)序列化成json字符串的操作。
1、结构体序列化
package main import ( " encoding /json" "fmt" ) type User struct { Name string Age int64 Sex string address string } func UserStruct() { user := User{ Name: "张三", Age: 32, Sex: "男", Address: "中国", } data, err := json.Marshal(&user) if err != nil { panic(err) } fmt.Printf("序列化后:%v\n", string(data)) } func main() { UserStruct() }
序列化后:
{"Name":"张三","Age":32,"Sex":"男","Address":"中国"}
2、Map序列化
package main import ( "encoding/json" "fmt" ) func MapToJson() { var user map[string]interface{} user = make(map[string]interface{}) user["Name"] = "张三" user["Age"] = 32 user["Sex"] = "男" user["Address"] = "中国" data, err := json.Marshal(&user) if err != nil { panic(err) } fmt.Printf("序列化后:%v\n", string(data)) } func main() { MapToJson() }
序列化后:
{"Address":"中国","Age":32,"Name":"张三1111","Sex":"男"}
3、切片序列化
package main
import (
"encoding/json"
"fmt"
)
func SliceToJson() {
var slice []map[string]interface{}
s1 := make(map[string]interface{})
s1["Name"] = "张三"
s1["Age"] = 32
s1["Sex"] = "男"
s1["Address"] = "中国"
slice = append (slice, s1)
s2 := make(map[string]interface{})
s2["Name"] = "张三"
s2["Age"] = 32
s2["Sex"] = "男"
s2["Address"] = "中国"
slice = append(slice, s2)
data, err := json.Marshal(&slice)
if err != nil {
panic(err)
}
fmt.Printf("序列化后:%v\n", string(data))
}
func main() {
SliceToJson()
}
序列化后:
[{"Address":"中国","Age":32,"Name":"张三","Sex":"男"},{"Address":"中国","Age":32,"Name":"张三","Sex":"男"}]
4、基本数据类型序列化
package main import ( "encoding/json" "fmt" ) func BasicToInt() { var num int64 = 1987 data, err := json.Marshal(num) if err != nil { panic(err) } fmt.Printf("序列化后:%v\n", string(data)) } func main() { BasicToInt() }
序列化后:
1987
基本数据类型无键值对 ,直接转成了字符串,把基本数据类型序列化,意义不大。
字段大小写问题:tag标签
package main import ( "encoding/json" "fmt" ) type User struct { Name string `json:"name"` Age int64 `json:"age"` Sex string `json:"sex"` Address string `json:"address"` } func TagToJson() { user := User{ Name: "张三", Age: 32, Sex: "男", Address: "中国", } data, err := json.Marshal(&user) if err != nil { panic(err) } fmt.Printf("序列化后:%v\n", string(data)) } func main() { TagToJson() }
序列化后:
{"name":"张三","age":32,"sex":"男","address":"中国"}
注意结构体字段小写,是不能被序列化的,字段小写,跨包是访问不到的。
json反序列化
是指,将json字符串序列化成对应的数据类型(结构体、map、切片)的操作。
1、结构体反序列化
import (
"encoding/json"
"fmt"
)
type User struct {
Name string
Age int64
Sex string
Address string
}
func JsonToStruct(){
v:="{\"Name\":\"张三\",\"Age\":32,\"Sex\":\"男\",\"Address\":\"中国\"}"
var user User
err:=json.Unmarshal([] byte (v),&user)
if err != nil {
panic(err)
}
fmt.Printf("反序列化后:name::%v\n", user.Name)
}
func main() {
//StructToJson()
JsonToStruct()
}
反序列化后:
name::张三
2、map反序列化
package main import ( "encoding/json" "fmt" ) func JsonToMap() { v := "{\"Name\":\"张三1111\",\"Age\":32,\"Sex\":\"男\",\"Address\":\"中国\"}" var m map[string]interface{} err := json.Unmarshal([]byte(v), &m) if err != nil { panic(err) } fmt.Printf("反序列化后:m::%v\n", m) } func main() { //MapToJson() JsonToMap() }
反序列化后:
m::map[Name:张三1111 Age:32 Sex:男 Address:中国]
3、切片反序列化
package main import ( "encoding/json" "fmt" ) func JsonToSlice() { var sclice [] map[string]interface{} v := "[{\"Address\":\"中国\",\"Age\":32,\"Name\":\"张三\",\"Sex\":\"男\"},{\"Address\":\"中国\",\"Age\":32,\"Name\":\"张三\",\"Sex\":\"男\"}]" err := json.Unmarshal([]byte(v), &sclice) if err != nil { panic(err) } fmt.Printf("序列化后:%v\n", sclice) } func main() { //SliceToJson() JsonToSlice() }
反序列化后:
[map[Sex:男 Address:中国 Age:32 Name:张三] map[Address:中国 Age:32 Name:张三 Sex:男]]
小结
在反序列化json字符串时,要确保反序列化后的数据类型与原先序列化前的数据类型保持一致。