Golang json 解析与生成
文章目录
- 1.解析 json
- 1.1 map[string]interface{} 存储 json
- 1.2 struct 存储 json
- 1.3 []map[string]interface{} 解析 json 数组
- 2.生成 JSON
- 2.1 struct 序列化为 json
- 2.2 map[string]interface{} 序列化为 json
- 2.3 一个较为复杂的例子
- 2.3.1 使用 struct + slice
- 2.3.2 使用 map[string]interface{} + []interface{}
- 参考文献
JSON(Javascript Object Notation)是一种轻量级的数据交换语言,以文字为基础,具有自我描述性且易于阅读。尽管 JSON 是 JavaScript 的一个子集,但 JSON 是独立于语言的文本格式,并且采用了类似于 C 语言家族的一些习惯。JSON 与 XML 最大的不同在于 XML 是一个完整的标记语言,而 JSON 不是。JSON由于比 XML 更小、更快,更易解析,以及浏览器的內建支持,使得其更适用于网络数据传输领域。
Golang 自带的 JSON 解析库 encoding/json,可以用来将结构化数据序列化成 json 字符串或从 json 字符串中解析出我们想要的数据。
1.解析 json
1.1 map[string]interface{} 存储 json
给一个较为复杂的 json 字符串,包含数组,数组的元素是 json 对象。我们需要取出数组第一个元素中的某一个字段值。其它的解析均可参考下面的代码。
package mainimport ("encoding/json""fmt"
)func main() {jsonStr := []byte(`{"uin":1589276509,"feedID":10000,"videos":[{"picture":"http://qqpublic.qpic.cn/avatar.jpg","duration":"839"}]}`)var jsonMap map[string]interface{}if err := json.Unmarshal(jsonStr, &jsonMap); err!=nil {fmt.Printf("json decode failed, err=%v", err)return}if value, ok := jsonMap["videos"]; ok {fmt.Printf("value=%#v\n", value)if sliceValue, ok := value.([]interface{}); ok {if mapValue, ok := sliceValue[0].(map[string]interface{}); ok {if duration, ok := mapValue["duration"]; ok {fmt.Printf("d=%v,type=%T\n", duration, duration)}}}}
}
程序输出:
value=[]interface {}{map[string]interface {}{"picture":"http://qqpublic.qpic.cn/avatar.jpg", "duration":"839"}}
d=839,type=string
解析 json 字符串时,需要注意如下几点:
(1)Golang 类型和 JSON 类型的对应关系如下:
map[string]interface{} 代表 JSON 对象
[]interface{} 代表 JSON 数组
bool 代表 JSON boolean
float64 代表 JSON number
string 代表 JSON string
nil 代表 JSON null
1.2 struct 存储 json
如果我们事先知道 JSON 串,那么可以指定具体的 struct 来存储解析后的 json。可以通过在线工具Golang: Convert JSON to Struct快速将 JOSN 转为 Go struct。
package mainimport ("fmt""encoding/json"
)type FeedsItem struct {Title string `json:"string_title"`Score int `json:"uint32_score"`AiKongbuLevel int `json:"uint32_ai_kongbu_level"`AiDisuLevel int `json:"uint32_ai_disu_level"`AiBiaotidangLevel int `json:"uint32_ai_biaotidang_level"`AiUnsocialLevel int `json:"uint32_ai_unsocial_level"`
}func main() {data:=`[{"uint32_feed_pos": 1,"string_title": "它才是“天然补血王”,女性隔三差五吃,美容驻颜,气色更红润","uint32_score": 4,"uint32_ai_kongbu_level": 0,"uint32_ai_disu_level": 0,"uint32_ai_biaotidang_level": 1,"uint32_ai_unsocial_level": 0}, {"uint32_feed_pos": 2,"string_title": "7岁的火星男孩,顺利通过测谎仪,现在为何消失不见了?","uint32_score": 4,"uint32_ai_kongbu_level": 0,"uint32_ai_disu_level": 0,"uint32_ai_biaotidang_level": 0,"uint32_ai_unsocial_level": 0}]`var feedsInfo []FeedsItem//第二个参数必须是指针,否则无法接收解析后的数据if err := json.Unmarshal([]byte(data), &feedsInfo); err != nil {fmt.Printf("json.Unmarshal() failed, err=%v data=%s\n", err, data)return}fmt.Printf("jsonMap=%#v\n", feedsInfo)
}
编译运行输出:
jsonMap=[]main.FeedsItem{main.FeedsItem{Title:"它才是“天然补血王”,女性隔三差五吃,美容驻颜,气色更红润", Score:4, AiKongbuLevel:0, AiDisuLevel:0, AiBiaotidangLevel:1, AiUnsocialLevel:0}, main.FeedsItem{Title:"7岁的火星男孩,顺利通过测谎仪,现在为何消失不见了?", Score:4, AiKongbuLevel:0, AiDisuLevel:0, AiBiaotidangLevel:0, AiUnsocialLevel:0}}
1.3 []map[string]interface{} 解析 json 数组
如果 json 字符串是一个 json 数组,除了可以使用 struct 来解析,也可以使用 []map[string]interface{} 来解析。
package mainimport ("fmt""encoding/json"
)func main() {s := `[{"id":300001,"exp_layer":"string","buckets":"1,2,3"},{"id":300002,"exp_layer":"test2","buckets":"4"}]`var jsonArray []map[string]interface{}if err := json.Unmarshal([]byte(s), &jsonArray); err!=nil {fmt.Printf("json decode failed, err=%v value=%v\n", err, s)return} fmt.Printf("jsonArray=%+v\n", jsonArray)
}
输出结果:
jsonArray=[map[exp_layer:string buckets:1,2,3 id:300001] map[id:300002 exp_layer:test2 buckets:4]]
2.生成 JSON
解析 json 时,可以使用 map[string]interface{} 或者 struct 来存储解析后的数据。同样地,我们可以将任意 Golang 对象序列化为 JSON。
Golang 中,JSON 对象表示主要有两种方式,一种是 struct,另一种是 map[string]interface{}。在表示数组时,分别使用具体类型的切片和任意类型的切片 []interface{}。
2.1 struct 序列化为 json
假设我们有如下一个结构体 Student 及其一个实例对象 st,将其序列化为 json,具体实现如下:
package mainimport ("encoding/json""fmt"
)type Student struct {Name string `json:"name"`Age intgender stringClass *Class `json:"class"`
}type Class struct {Name stringGrade int
}func main() {//实例化一个数据结构,用于生成 json 字符串st := Student{Name: "张三",Age: 18,gender: "男",}//指针变量cla := new(Class)cla.Name = "1班"cla.Grade = 3st.Class=cla//Marshal失败时 err != niljsonStu, err := json.Marshal(st)if err != nil {fmt.Println("生成json字符串错误")}//jsonStu是[]byte类型,转化成string类型便于查看fmt.Println(string(jsonStu))
}
程序输出结果:
{"name":"张三","Age":18,"class":{"Name":"1班","Grade":3}}
阅读以上代码可以看出:
(1)只要是可导出成员(变量首字母大写),都可以转成 json。因成员变量 gender 是不可导出的,故无法转成 json;
(2)如果变量打上了 json 标签,如 Name 旁边的 json:"name"
,那么转化成的 json key 就用该标签 “name”,否则取字段名作为 key,如 “Age”;
(3)指针变量,编码时自动转换为它所指向的值,如 Class 变量;
(4)强调一句,序列化成功后的 json 字符串是纯粹的字符串。
2.2 map[string]interface{} 序列化为 json
package mainimport ("encoding/json""fmt"
)func main() {m := make(map[string]interface{})m["Name"]="张三"m["Age"]=18m["Gender"]="男"jsonObject := make(map[string]interface{})jsonObject["Name"]="1班"jsonObject["Grade"]=3m["Class"]=jsonObject//将 map[string]interface{} 转换为 jsonsJson, _ := json.Marshal(m)fmt.Printf("sJson=%v\n", string(sJson))
}
编译运行输出:
sJson={"Age":18,"Class":{"Grade":3,"Name":"1班"},"Gender":"男","Name":"张三"}
2.3 一个较为复杂的例子
假如需要生成如下一个较为复杂的 json:
{"requests": [{"positions": [{"ads": [{"bid_result": "1","ecpm": "1.1","view_id": "Y940raTWuc2bAbPtq1lEc"}, {"bid_result": "2","ecpm": "2.2","view_id": "L37Qw!KwBORErDPbViQ"}]}]}]
}
其中,requests 为一个数组,数组的元素是一个 json 对象,该对象只有一个成员 positions;positions 也是一个数组,数组的元素也是一个 json 对象,该对象也只有一个成员 ads;ads 同样还是数组,数组元素还是一个 json 对象。
2.3.1 使用 struct + slice
因为在 Golang 中,一个 json 对象可以使用 struct 表示,json 中的数组可以使用 slice 来表示,于是我们可以使用 struct 和 slice 来表示上面的 json。
package mainimport ("encoding/json""fmt"
)type Request struct{Requests []RequestValue `json:"requests"`
}type RequestValue struct {Positions []PositionValue `json:"positions"`
}type PositionValue struct {Ads []AdsValue `json:"ads"`
}type AdsValue struct {Bid_result string `json:"bid_result"` Ecpm string `json:"ecpm"`View_id string `json:"view_id"`
}func main() {positionValue := PositionValue{Ads: []AdsValue{AdsValue{Bid_result:"1",Ecpm:"1.1",View_id:"Y940raTWuc2bAbPtq1lEc",},AdsValue{Bid_result:"2",Ecpm:"1.2",View_id:"L37Qw!KwBORErDPbViQ",},},}requestValue := RequestValue{Positions: []PositionValue{positionValue},}request := Request{Requests: []RequestValue{requestValue}}//将 struct 转换为 jsonsJson, _ := json.Marshal(request)fmt.Printf("sJson=%v\n", string(sJson))
}
编译运行输出:
sJson={"requests":[{"positions":[{"ads":[{"bid_result":"1","ecpm":"1.1","view_id":"Y940raTWuc2bAbPtq1lEc"},{"bid_result":"2","ecpm":"1.2","view_id":"L37Qw!KwBORErDPbViQ"}]}]}]}
2.3.2 使用 map[string]interface{} + []interface{}
同样地,可以使用 map[string]interface{} 来表示任意的 json,如果元素是数组,可以使用 []interface{}。
package mainimport ("encoding/json""fmt"
)func main() {//json 对象 adValue := make(map[string]interface{})adValue["bid_result"]="1"adValue["ecpm"]="1.1"adValue["view_id"]="Y940raTWuc2bAbPtq1lEc"adValue1 := make(map[string]interface{})adValue1["bid_result"]="2"adValue1["ecpm"]="1.2"adValue1["view_id"]="L37Qw!KwBORErDPbViQ"//json 对象,只有一个成员 ads,且 ads 是一个 json 对象数组ads := make(map[string]interface{})ads["ads"]=[]interface{}{adValue, adValue1}//json 对象,只有一个成员 positions,且 positions 是一个 json 对象数组positions := make(map[string]interface{})positions["positions"]=[]interface{}{ads}//json 对象,只有一个成员 requests,且 requests 是一个 json 对象数组requests := make(map[string]interface{})requests["requests"] = []interface{}{positions}//将 map[string]interface{} 转换为 jsonsJson, _ := json.Marshal(requests)fmt.Printf("sJson=%v\n", string(sJson))
}
编译运行输出:
sJson={"requests":[{"positions":[{"ads":[{"bid_result":"1","ecpm":"1.1","view_id":"Y940raTWuc2bAbPtq1lEc"},{"bid_result":"2","ecpm":"1.2","view_id":"L37Qw!KwBORErDPbViQ"}]}]}]}
输出结果与使用 struct 相同。相比于 struct,使用 map[string]interface{} 更加的简洁,因为省去了 struct 的定义。
参考文献
[1] Golang中文官网.Package json
[2] Go的json解析:Marshal与Unmarshal
[3] stackoverflow.panic: json: cannot unmarshal array into Go value of type main.Structure
[4] Introducing JSON
Golang json 解析与生成相关推荐
- json解析对应的value为null_解决golang json解析出现值为空的问题
我是通过beego框架,将请求过来的json进行解析,并将值保存在结构体中 --------------------1--------------------- request := UpdateCo ...
- Swift - 使用原生库进行 JSON 解析和生成
快速入门 JSON(JavaScript Object Notation)是应用在 JavaScript 语言上的数据格式,常用于网络数据交换和存储.Apple 在Foundation模块中集成了 J ...
- iOS json解析 和生成json串
1.生成json字符串 NSData * jsonData = [NSJSONSerialization dataWithJSONObject:detailDic options:0 error:ni ...
- Golang json解析踩坑
背景 众所周知,PHP是弱类型,Go是强类型,所以Go的json解析注定曲折. 有一段json如下: {"name":"Gopher","age&qu ...
- golang json解析
前言 Go 语言自带的 encode/json 包提供了对 JSON 数据格式的编码和解码能力. 解析 JSON 的关键,其实在于如何声明存放解析后数据的变量的类型. 此外使用 json 编码还会有几 ...
- Go实战--golang中使用号称全世界最快的JSON解析器json-iterator(json-iterator/go)
生命不止,继续go go go!!! 号外号外,差不一条广告,我的博客六月到十一月UV的地域分布: golang中的使用json一点也不陌生,golang为我们提供了官方的encoding/json: ...
- golang xml和json的解析与生成
golang中解析xml时我们通常会创建与之对应的结构体,一层层嵌套,完成复杂的xml解析. package main;import ("encoding/xml""fm ...
- 细说Golang的JSON解析
之前一直写一些动态语言,觉得解析JOSN还是很简单的,往往只需要几行代码就能拿到解析好的JSON对象.Go语言自带的json包可以让你在程序中方便的读取和写入 JSON 数据.生成JSON场景相对简单 ...
- Golang Json文件解析为结构体工具-json2go
代码地址如下: http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出 ...
最新文章
- 9.2 图像类型(灰度图像、彩色图像、二值图像以及图像间的转换)
- GUN Make指南
- centos7花里胡哨之终端美化
- [shell进阶]——shell多线程
- rdb和aof优势劣势
- android 按钮点击声音,如何在Android中单击按钮时播放声音?
- Scikit-Learn库概述
- 文件管理类函数(1)
- Smart3D系列教程
- Zcurd与Eova对比,欢迎吐槽!
- ZedGraph _WINFORM中设置ZEDGRAPH的曲线符号SYMBOL以及对应关系
- 外贸常用术语_13个常用的国际贸易术语详解
- 专访王豫翔:编程道路上的“三少三多”
- [****ViewController scrollViewDidScroll:]: message sent to deallocated instance 0x12d6c22f0
- 还在用电脑多控手机?你out了,手机多控手机,全新神器
- win10电池图标不能调亮度_win10屏幕亮度无法调节?一招解决Win10电脑亮度调节失灵...
- Houdini学习笔记——【案例二】消散文字制作
- Vue3 项目遇到的问题
- matlab fpga 移植,使用MATLAB,Simulink以及基于模型的设计实现把电机控制算法移植到Zynq平台...
- 中国机械对流烘箱行业市场供需与战略研究报告