实际业务开发中,json处理很常见,本文总结一下go语言对json的处理。
目录
1.encoding/json 包
1.1 Marshal 函数
(1)原始字段名
(2)字段重命名
1.2 Unmarshal函数
(1)原始字段名
(2)字段重命名
2.常规方法处理嵌套json
3.github.com/tidwall/gjson处理嵌套json
1.encoding/json 包
1.1 Marshal 函数
Marshal将Go语言中的数据类型转换为JSON格式的数据。
(1)原始字段名
package main
import (
"encoding/json"
"fmt"
)
type UserInfo struct {
Id int
Age int
Name string
Addr string
}
// struct -> json string
func struct_to_jsonstring() {
user := UserInfo{Name: "张三", Age: 18, Addr: "北京", Id: 110}
b, err := json.Marshal(user)
if err != nil {
fmt.Println("转换失败", err)
return
}
fmt.Println(string(b))
}
func main() {
fmt.Println("======== struct -> json string =======")
struct_to_jsonstring()
}
运行结果:
(2)字段重命名
package main
import (
"encoding/json"
"fmt"
)
// 重命名
type UserInfo struct {
Id int `json:"id_other"`
Age int `json:"age_other"`
Name string `json:"name_other"`
Addr string `json:"addr_other"`
}
// struct -> json string
func struct_to_jsonstring() {
user := UserInfo{Name: "张三", Age: 18, Addr: "北京", Id: 110}
b, err := json.Marshal(user)
if err != nil {
fmt.Println("转换失败", err)
return
}
fmt.Println(string(b))
}
func main() {
fmt.Println("======== struct -> json string =======")
struct_to_jsonstring()
}
运行结果如下:
1.2 Unmarshal函数
Unmarshal将 JSON格式的数据转换为 Go 语言中的数据类型。
(1)原始字段名
package main
import (
"encoding/json"
"fmt"
)
type UserInfo struct {
Id int
Age int
Name string
Addr string
}
// json string -> struct
func jsonstring_to_struct() {
s := `{"Id": 110,"Age": 18,"Name": "张三","Addr": "北京"}`
var user UserInfo
err := json.Unmarshal([]byte(s), &user)
if err != nil {
fmt.Println("转换失败", err)
return
}
fmt.Println(user)
fmt.Println(user.Id, user.Name, user.Age, user.Addr)
}
func main() {
fmt.Println("======== json string -> struct =======")
jsonstring_to_struct()
}
运行结果如下:
(2)字段重命名
package main
import (
"encoding/json"
"fmt"
)
// 重命名
type UserInfo struct {
Id int `json:"id_other"`
Age int `json:"age_other"`
Name string `json:"name_other"`
Addr string `json:"addr_other"`
}
// json string -> struct
func jsonstring_to_struct() {
s := `{"id_other": 220, "age_other": 16, "name_other": "李四", "addr_other": "上海"}`
var user UserInfo
err := json.Unmarshal([]byte(s), &user)
if err != nil {
fmt.Println("转换失败", err)
return
}
fmt.Println(user)
fmt.Println(user.Id, user.Name, user.Age, user.Addr)
}
func main() {
fmt.Println("======== json string -> struct =======")
jsonstring_to_struct()
}
运行结果如下:
2.常规方法处理嵌套json
以下将演示从文件读取json然后进行反序列化,通过反序列化后的对象来读取各个字段的值。
result.json
{
"title": "信号准入检查结果",
"time": "202230712123456789",
"author":{
"name":"張三",
"age":18
},
"body":[
{
"group_item": "定位类",
"detail_list": [
{
"check_item": "信号中的所有项",
"check_list": [
{"priority": "P0", "type": "完整性检查", "check_desc": "具体描述1。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary1.txt"},
{"priority": "P0", "type": "连续性检查", "check_desc": "具体描述2。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary2.txt"}
]
},
{
"check_item": "经纬度",
"check_list": [
{"priority": "P0", "type": "异常检测(跳变)", "check_desc": "具体描述3。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary3.txt"},
{"priority": "P0", "type": "异常检测(静止)", "check_desc": "具体描述4。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary4.txt"}
]
}
]
},
{
"group_item": "感知类",
"detail_list":[
{
"check_item": "此类中所有必须项",
"check_list": [
{"priority": "P0", "type": "完整性检查", "check_desc": "具体描述5。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary5.txt"},
{"priority": "P0", "type": "连续性检查", "check_desc": "具体描述6。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary8.txt"}
]
},
{
"check_item": "障碍物坐标信号『position』",
"check_list": [
{"priority": "P0", "type": "跳变异常", "check_desc": "具体描述7。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary7.txt"},
{"priority": "P0", "type": "超出路面异常", "check_desc": "具体描述8。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary8.txt"}
]
}
]
}
]
}
package main
import (
"encoding/json"
"io/ioutil"
"fmt"
)
// 复杂结构体和json
type CheckResultInfo struct {
Title string `json:"title"`
Time string `json:"time"`
Author AuthorInfo `json:"author"`
Body []BodyInfo `json:"body"`
}
type AuthorInfo struct {
Name string `json:"name"`
Age int `json:"age"`
}
type BodyInfo struct {
GroupItem string `json:"group_item"`
DetailList []DetailInfo `json:"detail_list"`
}
type DetailInfo struct {
CheckItem string `json:"check_item"`
CheckList []CheckInfo `json:"check_list"`
}
type CheckInfo struct {
Priority string `json:"priority"`
Type string `json:"type"`
CheckDesc string `json:"check_desc"`
Result string `json:"result"`
ConclusionDetail string `json:"conclusion_detail"`
DetailReason string `json:"detail_reason"`
}
// 常規方法解析json字符串
func common_deal_nestjson() {
path := "./result.json"
f, _ := ioutil.ReadFile(path)
var result CheckResultInfo
json.Unmarshal(f, &result)
for _, iv := range result.Body {
fmt.Println(iv.GroupItem)
for _, nv := range iv.DetailList {
fmt.Println(nv.CheckItem)
for _, cv := range nv.CheckList {
fmt.Println(cv.Priority,
cv.Type,
cv.CheckDesc,
cv.Result,
cv.ConclusionDetail,
cv.DetailReason)
}
}
}
}
func main() {
fmt.Println("======== common deal nestjson =======")
common_deal_nestjson()
}
运行结果如下所示:
如下演示复杂json字符串转map用法,具体如下:
package main
import (
"encoding/json"
"log"
"fmt"
)
// nestjson string -> map
func nestjsonstring_to_map() {
jsonStr := `
{
"name": "hello tree",
"occupation": "程序员",
"info": {
"age": 18,
"addr": "广州"
},
"work_experience":[
{
"company1": "1234"
},
{
"company2": "5678"
}
]
}`
// 序列化成map
anyMap := make(map[string]interface{}, 0)
if err := json.Unmarshal([]byte(jsonStr), &anyMap); err != nil {
panic(err)
}
log.Println("map result:", anyMap)
fmt.Println(anyMap["name"], anyMap["occupation"], (anyMap["info"]), anyMap["work_experience"])
}
func main() {
fmt.Println("======== nestjson string -> map =======")
nestjsonstring_to_map()
}
运行方法如下:
3.github.com/tidwall/gjson处理嵌套json
gjson不是标准库的包,需要使用go get github.com/tidwall/gjson安装。
gjson处理json字符串,不需要反序列化为对象二直接读取json字符串各个字段的值。
package main
import (
"encoding/json"
"log"
"fmt"
"github.com/tidwall/gjson"
)
// 复杂结构体和json
type CheckResultInfo struct {
Title string `json:"title"`
Time string `json:"time"`
Author AuthorInfo `json:"author"`
Body []BodyInfo `json:"body"`
}
type AuthorInfo struct {
Name string `json:"name"`
Age int `json:"age"`
}
type BodyInfo struct {
GroupItem string `json:"group_item"`
DetailList []DetailInfo `json:"detail_list"`
}
type DetailInfo struct {
CheckItem string `json:"check_item"`
CheckList []CheckInfo `json:"check_list"`
}
type CheckInfo struct {
Priority string `json:"priority"`
Type string `json:"type"`
CheckDesc string `json:"check_desc"`
Result string `json:"result"`
ConclusionDetail string `json:"conclusion_detail"`
DetailReason string `json:"detail_reason"`
}
var jsonStr = `
{
"title": "信号准入检查结果",
"time": "202230712123456789",
"author":{
"name":"張三",
"age":18
},
"body":[
{
"group_item": "定位类",
"detail_list": [
{
"check_item": "信号中的所有项",
"check_list": [
{"priority": "P0", "type": "完整性检查", "check_desc": "具体描述1。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary1.txt"},
{"priority": "P0", "type": "连续性检查", "check_desc": "具体描述2。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary2.txt"}
]
},
{
"check_item": "经纬度",
"check_list": [
{"priority": "P0", "type": "异常检测(跳变)", "check_desc": "具体描述3。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary3.txt"},
{"priority": "P0", "type": "异常检测(静止)", "check_desc": "具体描述4。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary4.txt"}
]
}
]
},
{
"group_item": "感知类",
"detail_list":[
{
"check_item": "此类中所有必须项",
"check_list": [
{"priority": "P0", "type": "完整性检查", "check_desc": "具体描述5。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary5.txt"},
{"priority": "P0", "type": "连续性检查", "check_desc": "具体描述6。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary8.txt"}
]
},
{
"check_item": "障碍物坐标信号『position』",
"check_list": [
{"priority": "P0", "type": "跳变异常", "check_desc": "具体描述7。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary7.txt"},
{"priority": "P0", "type": "超出路面异常", "check_desc": "具体描述8。", "result": "通过", "conclusion_detail":"ok", "detail_reason": "/tmp/sianal/summary8.txt"}
]
}
]
}
]
}
`
func gson_deal_nestjson() {
// json字符串反序列化成map
anyMap := make(map[string]interface{}, 0)
if err := json.Unmarshal([]byte(jsonStr), &anyMap); err != nil {
panic(err)
}
log.Println("Unmarshal to map:", anyMap)
// json字符串反序列化成对象
res := CheckResultInfo{}
if err := json.Unmarshal([]byte(jsonStr), &res); err != nil {
panic(err)
}
log.Println("Unmarshal to struct:", res)
// 不反序列化,直接操作json字符串,只读取单个key,比較适合复杂的json字符串
title := gjson.Get(jsonStr, "title")
time := gjson.Get(jsonStr, "time")
body := gjson.Get(jsonStr, "body")
item1 := body.Array()[0]
item1_name := item1.Get("group_item")
detail_list := item1.Get("detail_list")
detail_item := detail_list.Array()[0]
check_item := detail_item.Get("check_item")
log.Println("title, time, item1_name, check_item: ", title, time, item1_name, check_item)
log.Println("author info: ", gjson.Get(jsonStr, "author.name"),
gjson.Get(jsonStr, "author.age").Int())
check_list := detail_item.Get("check_list")
check_list_item := check_list.Array()[1]
log.Println("priority, type, check_desc, result, conclusion_detail, detail_reason: ",
check_list_item.Get("priority"),
check_list_item.Get("type"),
check_list_item.Get("check_desc"),
check_list_item.Get("result"),
check_list_item.Get("conclusion_detail"),
check_list_item.Get("detail_reason"))
}
func main() {
fmt.Println("======== gson deal nestjson =======")
gson_deal_nestjson()
}
运行结果如下所示: