[系列] Go 如何解析 JSON 数据?
概述
最近掉进需求坑了,刚爬上来,评估排期出现了严重问题,下面三张图很符合当时的心境。
谈需求

估排期

开始干

为啥会这样,我简单总结了下:
- 与第三方对接。
- 跨团队对接。
- 首次用 Go 做项目。
- 业务流程没屡清楚就出排期(大坑)。
- 需求调整后未进行调整排期(大坑)。
有了这次经验,后期关于如何评估排期也可以和大家唠唠。
废话不多说了,进入今天主题。
今天给大家分享用 Go 如何解析 JSON 数据,包含三种情况,强类型解析、弱类型解析、返回结构不确定 等。
JSON 结构
比如,请求了手机归属地的接口,json 数据返回如下:
{
"resultcode": "200",
"reason": "Return Successd!",
"result": {
"province": "浙江",
"city": "杭州",
"areacode": "0571",
"zip": "310000",
"company": "中国移动",
"card": ""
}
}
思路是这样的:
1.先将 json 转成 struct。
2.然后 json.Unmarshal() 即可。
json 转 struct ,自己手写就太麻烦了,有很多在线的工具可以直接用,我用的这个:
https://mholt.github.io/json-to-go/
在左边贴上 json 后面就生成 struct 了。
用代码实现下:
type MobileInfo struct {
Resultcode string `json:"resultcode"`
Reason string `json:"reason"`
Result struct {
Province string `json:"province"`
City string `json:"city"`
Areacode string `json:"areacode"`
Zip string `json:"zip"`
Company string `json:"company"`
Card string `json:"card"`
} `json:"result"`
}
func main() {
jsonStr := `
{
"resultcode": "200",
"reason": "Return Successd!",
"result": {
"province": "浙江",
"city": "杭州",
"areacode": "0571",
"zip": "310000",
"company": "中国移动",
"card": ""
}
}
`
var mobile MobileInfo
err := json.Unmarshal([]byte(jsonStr), &mobile)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(mobile.Resultcode)
fmt.Println(mobile.Reason)
fmt.Println(mobile.Result.City)
}
输出:
200
Return Successd!
杭州
完美解析。
到这问题还没结束,思考下这些问题:
如果 json 格式的数据类型不确定怎么办?
如果 json 格式的数据 result 中参数不固定怎么办?
思路是这样的:
去 github 上找开源类库,哈哈,我使用的是这个:
https://github.com/mitchellh/mapstructure
咱们一起学习下,先解决第一个问题,数据类型不确定怎么办?
先定义一个 string 类型的 resultcode,json 却返回了 int 类型的 resultcode。
看文档有一个弱类型解析的方法 WeakDecode(),咱们试一下:
type MobileInfo struct {
Resultcode string `json:"resultcode"`
}
func main() {
jsonStr := `
{
"resultcode": 200
}
`
var result map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &result)
if err != nil {
fmt.Println(err.Error())
}
var mobile MobileInfo
err = mapstructure.WeakDecode(result, &mobile)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(mobile.Resultcode)
}
输出:
200
第一个问题已解决。
再解决第二个问题,result 中参数不固定怎么办?
这个就不用上面的例子了,看下官方提供的例子 Example (EmbeddedStruct) 。
type Family struct {
LastName string
}
type Location struct {
City string
}
type Person struct {
Family `mapstructure:",squash"`
Location `mapstructure:",squash"`
FirstName string
}
func main() {
input := map[string]interface{}{
"FirstName": "Mitchell",
"LastName": "Hashimoto",
"City": "San Francisco",
}
var result Person
err := mapstructure.Decode(input, &result)
if err != nil {
panic(err)
}
fmt.Println(result.FirstName)
fmt.Println(result.LastName)
fmt.Println(result.City)
}
输出:
Mitchell
Hashimoto
San Francisco
使用的是 mapstructure 包,struct tag 标识不要写 json,要写 mapstructure。
其他情况自己探索吧,比如: Example (Tags)。
go-gin-api 系列文章
- 7. 路由中间件 - 签名验证
- 6. 路由中间件 - Jaeger 链路追踪(实战篇)
- 5. 路由中间件 - Jaeger 链路追踪(理论篇)
- 4. 路由中间件 - 捕获异常
- 3. 路由中间件 - 日志记录
- 2. 规划项目目录和参数验证
- 1. 使用 go modules 初始化项目
[系列] Go 如何解析 JSON 数据?的更多相关文章
- pyspider示例代码二:解析JSON数据
本系列文章主要记录和讲解pyspider的示例代码,希望能抛砖引玉.pyspider示例代码官方网站是http://demo.pyspider.org/.上面的示例代码太多,无从下手.因此本人找出一下 ...
- 使用Python解析JSON数据的基本方法
这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下: ----------------------------------- ...
- 使用jQuery解析JSON数据
我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. 上例中得到的JSON数据如下,是一个嵌套JSON: {"comments&quo ...
- [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")
javascript eval函数解析json数据时为什么 加上圆括号?为什么要 eval这里要添加 “("("+data+")");//”呢? 原因在于: ...
- 用jquery解析JSON数据的方法以及字符串转换成json的3种方法
用jquery解析JSON数据的方法,作为jquery异步请求的传输对象,jquery请求后返回的结果是 json对象,这里考虑的都是服务器返回JSON形式的字符串的形式,对于利用JSONObject ...
- Android中使用Gson解析JSON数据的两种方法
Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下 Json是一种类似于XML的通用数据交换格式,具有比XML更高的 ...
- fastjson生成和解析json数据,序列化和反序列化数据
本文讲解2点: 1. fastjson生成和解析json数据 (举例:4种常用类型:JavaBean,List<JavaBean>,List<String>,List<M ...
- 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中
摘自:http://blog.csdn.net/mazhaojuan/article/details/8592015 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来 ...
- JSONKit解析json数据
先将第三方文件拖进工程 JSONKit.h和JSONKit.m 然后设置在ARC工程中添加MRC文件,如下图所示 #import "ViewController.h" #impor ...
随机推荐
- linux centos 一键安装环境
phpStudy for Linux 支持Apache/Nginx/Tengine/Lighttpd, 支持php5.2/5.3/5.4/5.5切换 已经在centos-6.5,debian-7.4. ...
- CSS常用函数calc等
>>CSS常用函数<<
- day6_python序列化之 json & pickle & shelve 模块
一.json & pickle & shelve 模块 json,用于字符串 和 python数据类型间进行转换pickle,用于python特有的类型 和 python的数据类型间进 ...
- codeforces2B.The least round way 题解 动态规划/模拟
题目出处:http://codeforces.com/problemset/problem/2/B 题目描述 给你一个 \(n \times n\) 的二维数组,它包含的元素都是非负整数.你需要寻找一 ...
- pip、conda 换国内源,大大提高下载速度
https://www.jianshu.com/p/b2d53904dd37 源就是下载地址了,换到国内的源下载速度真的快了近10倍,这里都用了清华的源 pip 只要新建一个配置文件,写上路径就行了 ...
- poj 1920 Towers of Hanoi
Towers of Hanoi Time Limit: 3000MS Memory Limit: 16000K Total Submissions: 2213 Accepted: 986 Ca ...
- H3C PPP基本配置
- Python--day48--ORM框架SQLAlchemy之子查询
一定要把第一次查询的结果作为一个结果再进行查询:代码后面加.subquery()标明是子查询 1,简单的子查询 #select * from (select * from tb) as B q1 = ...
- Python--day38---进程间通信--初识队列(multiprocess.Queue)之生产者,消费者模型
1,生产者消费者模型.py import random import time from multiprocessing import Queue, Process def producer(name ...
- H3C 环路避免机制四:定义最大值