go解析json

json标签

type Author struct {
    Name string `json:"name,omitempty"`
    Age  int32  `json:"age,string,omitempty"`
}

常见的两个标签是 string 和 omitempty,前者表示当前的整数或者浮点数是由 JSON 中的字符串表示的,而另一个字段 omitempty 会在字段为零值时,直接在生成的 JSON 中忽略对应的键值对,例如:“age”: 0、“author”: “” 等。标准库会使用 encoding/json.parseTag 函数来解析标签:

生成json

Marshal函数处理go的结构体

package main

import (
	"encoding/json"
	"os"
)

type ServerInfo struct {
	//标签有string,ServerName的值会进行二次JSON编码 “”
	ServerName  string `json:"serverName"`
	//ServerName2 string `json:"server_name_2,string"`
	//如果ServerIP为空,则不输出到JSON中
	ServerIP    string `json:"serverIP,omitempty"`
}

type Server struct {
	//ID不会导出到JSON
	ID int `json:"-"`
	ServerInfos []ServerInfo `json:"server_infos"`
	Description string `json:"description,string"`
	//tag中带有“,string”选项,在输出到JSON的时候会把该字段对应的值转换成JSON字符串
	Score  float32 `json:"score,string"`
}

func main(){
	s01 := ServerInfo{
		ServerName: "s1",
		ServerIP: "10.0.12.1",
	}
	s02 := ServerInfo{
		ServerName: "s2",
		ServerIP: "",
	}

	s := Server{
		ID:          3,
		Description: `描述信息`,
		Score: 		87.2,
	}

	s.ServerInfos = append(s.ServerInfos, s01,s02)
	b, _ := json.Marshal(s)
	os.Stdout.Write(b)
}

得到json字符串

{"server_infos":[{"serverName":"s1","serverIP":"10.0.12.1"},{"serverName":"s2"}],"description":"\"描述信息\"","score":"87.2"}

解析json

json里含数字时,如果直接用json.Unmarshal解析,会默认将数据转为float64,可能会丢失精度

1.已知json结构体组成

以下读取方法,不会丢失数字精度

type ServerInfo struct {
	//标签有string,ServerName的值会进行二次JSON编码 “”
	ServerName  string `json:"serverName"`
	//ServerName2 string `json:"server_name_2,string"`
	//如果ServerIP为空,则不输出到JSON中
	ServerIP    string `json:"serverIP,omitempty"`
}

type Server struct {
	//ID不会导出到JSON
	ID int `json:"-"`
	ServerInfos []ServerInfo `json:"server_infos"`
	Description string `json:"description,string"`
	//tag中带有“,string”选项,在输出到JSON的时候会把该字段对应的值转换成JSON字符串
	Score  float32 `json:"score,string"`
	Age    int `json:"age"`
}

	var s2 Server
	decoder := json.NewDecoder(bytes.NewReader(b))
	decoder.UseNumber()
	err := decoder.Decode(&s2)
	if err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Println(s2)
	fmt.Println(s2.Age,s2.Score)
	fmt.Println(reflect.TypeOf(s2.Age),reflect.TypeOf(s2.Score))

2.未知json数据结构

    decoder := json.NewDecoder(bytes.NewReader(b))
	decoder.UseNumber()
	s2 := make(map[string]interface{})
	err := decoder.Decode(&s2)
	if err != nil {
		fmt.Printf("json.Unmarshal failed, err:%v\n", err)
		return
	}
	fmt.Println(s2)
	fmt.Println(s2["age"],s2["score"])
	//打印结果:25 87.2
	fmt.Println(reflect.TypeOf(s2["age"]),reflect.TypeOf(s2["age"]))
	//打印类型:json.Number json.Number

3.自推断类型(推荐)

    data := `{"server_infos":[{"serverName":"s1","serverIP":"10.0.12.1"},{"serverName":"s2"}],"description":"\"描述信息\"","score":"87.2","age":25}`
	var tmp map[string]interface{}
	json.Unmarshal([]byte(data), &tmp)

	description := GetItemString(tmp,"description")
	fmt.Println(description)
	fmt.Println(reflect.TypeOf(description))

	score := GetItemString(tmp,"score")
	fmt.Println(score)
	fmt.Println(reflect.TypeOf(score))

	age := GetItemFloat64(tmp,"age")
	fmt.Println(age)
	fmt.Println(reflect.TypeOf(age))

	//繁琐解析法
	//fmt.Println(len(tmp["server_infos"].([]interface {})))
	//mapTmp1 := (tmp["server_infos"].([]interface {}))[0].
	//	(map[string]interface {})
	//fmt.Println(mapTmp1["serverName"])
	//fmt.Println(mapTmp1["serverIP"])

	//函数封装解析
	server_infos := GetItemArray(tmp,"server_infos")
	fmt.Println(server_infos)
	fmt.Println(reflect.TypeOf(server_infos[0]))

	serverName := GetItemString(server_infos[0].(map[string]interface{}),"serverName")
	fmt.Println(serverName)
	serverIP := GetItemString(server_infos[0].(map[string]interface{}),"serverIP")
	fmt.Println(serverIP)


	data1 := `{"data":{"t1":"sdd","t2":"sdsd","t3":{"y1":"sd","y2":"12"}}}`
	json.Unmarshal([]byte(data1), &tmp)
	test := GetItemMap(tmp,"data")
	fmt.Println(test)
	//fmt.Println(reflect.TypeOf(test))
	t3 := GetItemMap(test,"t3")
	fmt.Println(GetItemString(t3,"y2"))
	//fmt.Println(reflect.TypeOf(t3))


//函数
func GetItemArray(parent map[string]interface{}, key string) []interface{} {
	val, ok := parent[key].([]interface{})
	if ok {
		return val
	} else {
		return nil
	}
}
func GetItemMap(parent map[string]interface{}, key string) map[string]interface{} {
	val, ok := parent[key].(map[string]interface{})
	if ok {
		return val
	} else {
		return nil
	}
}
func GetItemString(parent map[string]interface{}, key string) string {
	val, ok := parent[key].(string)
	if ok {
		return val
	}
	return ""
}
func GetItemFloat64(parent map[string]interface{}, key string) float64 {
	val, ok := parent[key].(float64)
	if ok {
		return val
	}
	return 0
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值