json协议是一个数据互通桥梁, 和语言无关, 它起的作用相当于翻译官
比如要go里面的数据 转换为 java的数据
直接把go数据给java, 肯定是不行的, 比如java根本就不认识结构体
此时需要中间桥梁json , 因为json是java和go都能处理的
先将go的数据转换为json, 这样java再将json转换为自己语言的数据
golang --> 序列化为json字符串 -->网络传输到java程序-->反序列化为java相关数据
json 数据协议:
[ // 数组, 包含两个对象
{ // 一个大括号表示一个对象
"key1": 10,
"key2": "abc"
},
{ // 对象
"key3": 100,
"key4": "abcd",
"key5": [ // key的值为string, value的值可以为数组
"a",
"b"
]
}
]
go对json的操作
1. 导入: "encoding/json"
2.序列化(打包): json.Marshal(interface{}) -- 打包成json串
它接收一个一般类型, 即所有go类型的数据都可以打包成一个string
3.反序列化(解包): json.Unmarshal([]byte, &variable) -- 将json字符串解析为go的数据类型
将json串转换为[]byte, 再传入一个变量的地址
(即使是切片, map也要传入地址, 因为要修改的是它本身, 而不是修改它里面的值)
结构体与map的打包:
type Student struct {
Name string `json:"name"` // tag为字段打包后的别名, 即json串中的名称
Age int `json:"age"`
Address string `json:"address"` // 冒号前后不要打空格, 或者有警告
}
func main() {
var stu *Student = &Student {
Name : "张三",
Age : 20,
Address : "中国",
}
jsonStr := testStruct(stu)
fmt.Println(jsonStr)
var m map[string]interface{} = make(map[string]interface{})
m["name"] = "李四"
m["score"] = 88
m["phone"] = "110"
jsonStr = testMap(m)
fmt.Println(jsonStr)
}
// 结构体打包
func testStruct(stu *Student) string{
str, err := json.Marshal(stu)
if err != nil {
return ""
}
return string(str)
}
// map打包
func testMap(m map[string]interface{}) string {
mapStr , err := json.Marshal(m)
if err != nil {
return ""
}
return string(mapStr)
}
切片打包:
package main
import (
"fmt"
"encoding/json"
)
func main() {
// 声明切片
var slice []map[string]interface{}
// 声明并初始化map
var m1 map[string]interface{} = make(map[string]interface{})
m1["name"] = "stu1"
m1["score"] = 88
m1["phone"] = "110"
slice = append(slice, m1)
var m2 map[string]interface{} = make(map[string]interface{})
m2["name"] = "stu2"
m2["score"] = 80
m2["phone"] = "119"
slice = append(slice, m2)
jsonStr := testSlice(slice)
fmt.Println(jsonStr)
}
// slice打包
func testSlice(s []map[string]interface{}) string {
sliceStr , err := json.Marshal(s)
if err != nil {
return ""
}
return string(sliceStr)
}
/*
[
{
"name": "stu1",
"phone": "110",
"score": 88
},
{
"name": "stu2",
"phone": "119",
"score": 80
}
]
*/
从结果可以看到切片打包后是以中括号的形式
结构体和map打包是都以大括号的形式
在json中中括号表示数组, 大括号表示对象, 这和go的这三种数据类型表示的意思是相近的
反序列化:
func main() {
// 声明切片
var slice []map[string]interface{}
// 声明并初始化map
var m1 map[string]interface{} = make(map[string]interface{})
m1["name"] = "stu1"
m1["score"] = 88
m1["phone"] = "110"
slice = append(slice, m1)
var m2 map[string]interface{} = make(map[string]interface{})
m2["name"] = "stu2"
m2["score"] = 80
m2["phone"] = "119"
slice = append(slice, m2)
jsonStr := testSlice(slice)
fmt.Println(jsonStr)
var reverseStr []map[string]interface {} // 如果是结构体, 这个变量类型就用结构体
err := json.Unmarshal([]byte(jsonStr), &reverseStr)
if err != nil {
fmt.Printf("解包失败%v", err)
}
fmt.Println(reverseStr)
}
// slice打包
func testSlice(s []map[string]interface{}) string {
sliceStr , err := json.Marshal(s)
if err != nil {
return ""
}
return string(sliceStr)
}