http协议前后端的交互通过json字符串交互,在Go语言中,序列化与反序列化 需要结构体 的转化。
1、序列化为 Json 字符串
1.1 json.Marshl 序列化
func Marshal(v interface{}) ([]byte, error)
// 定义 Student类结构体
type Student struct {
Code int `json:"code"` // 使用tag,表示对应json的字段名
Message string `json:"message"`
Grades []GradeType `json:"grades"` // 结构体类数组
}
type GradeType struct {
GradeClass string `json:"gradeClass"`
Score ScoreType
}
type ScoreType struct {
Chinese int `json:"chinese"`
English int `json:"english"`
}
初始化结构体,通过json.Marshal转为json字符串
func main() {
stu := Student{
Code: 0,
Message: "success",
Grades: []GradeType{
GradeType{
GradeClass: "一年级",
Score: ScoreType{
Chinese: 99,
English: 88,
},
},
GradeType{
GradeClass: "二年级",
Score: ScoreType{
Chinese: 100,
English: 98,
},
},
},
}
fmt.Println(stu)
s, err := json.Marshal(stu)
if err != nil {
fmt.Println(err)
}
fmt.Println(s) // [123 34 99 111 100 101 34 58 48...23 135]
fmt.Printf("%T\n", s) // []uint8,这里为char字节数组类型
fmt.Println(string(s)) // 字节类型转 字符串,通过 string 直接转换
// {"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}
}
1.2 Golang 优雅的输出 json字符串
为增强json字符串可读性,可调用开源的
- 安装
go get -u github.com/tidwall/pretty
{"name": {"first":"Tom","last":"Anderson"}, "age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter", "friends": [
{"first": "Janet", "last": "Murphy", "age": 44}
]}
result = pretty.Pretty(example)
{
"name": {
"first": "Tom",
"last": "Anderson"
},
"age": 37,
"children": ["Sara", "Alex", "Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{
"first": "Janet",
"last": "Murphy",
"age": 44
}
]
}
2、反序列化为 struct 结构体
2.1 json.Unmarshl 反序列化
需求:将json字符串转为结构体,1)预先定义json对应的结构体类型;2)调用 json.Unmarshl
func Unmarshal(data []byte, v interface{}) error
type Student struct {
Code int `json:"code"` // 使用tag,表示对应json的字段名
Message string `json:"message"`
Grades []GradeType `json:"grades"` // 结构体类数组
}
type GradeType struct {
GradeClass string `json:"gradeClass"`
Score ScoreType
}
type ScoreType struct {
Chinese int `json:"chinese"`
English int `json:"english"`
}
func main() {
// 这里反引号表示不转意,即为string类型
resp := `{"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}`
var stu Student
err := json.Unmarshal([]byte(resp), &stu)
if err != nil {
log.Println(err)
}
log.Println(stu)
// 2021/08/12 23:37:19 {0 success [{一年级 {99 88}} {二年级 {100 98}}]}
}
2.2 处理 http请求
// http请求,得到json字符串 resp
resp, err := http.Get("api")
if err != nil{
fmt.Println(err)
}
var stu Student
err := json.Unmarshal([]byte(resp), &stu)
if err != nil {
log.Println(err)
}
log.Println(stu)
2.3 工具自动化生成 结构体
遇到http请求的多层嵌套json,莫慌,一键生成结构体,真香~
工具地址:https://mholt.github.io/json-to-go/
根据 定义好的 Json,自动生成结构体:
{
"code": 0,
"message": "success",
"grades": [
{
"gradeClass": "一年级",
"Score": {
"chinese": 99,
"english": 88
}
},
{
"gradeClass": "二年级",
"Score": {
"chinese": 100,
"english": 98
}
}
]
}
如下:
type AutoGenerated struct {
Code int `json:"code"`
Message string `json:"message"`
Grades []struct {
GradeClass string `json:"gradeClass"`
Score struct {
Chinese int `json:"chinese"`
English int `json:"english"`
} `json:"Score"`
} `json:"grades"`
}
3、注意点
大写