【Golang 接口自动化04】 解析接口返回JSON串
前言
上一次我们一起学习了如何解析接口返回的XML数据,这一次我们一起来学习JSON的解析方法。
JSON(Javascript Object Notation)是一种轻量级的数据交换语言,以文字为基础,具有自我描述性且易于让人阅读。XML是一个完整的标记语言,而JSON不是。JSON比XML更小、更快,更易解析,因此其被广泛应用于网络数据传输领域。
Go语言的标准库已经非常好的支持了JSON,可以很容易的对JSON数据进行编、解码的工作。下面我们通过一些实例一起来学习。
首先我们假设我们的接口返回的JSON数据如下:
{ "code": "00",
"message": "SUCCESS",
"describe": "成功",
"resultInfo": { "uniqueNumber": "201808161133401673324075025000035" }
}
解析到结构体
这种方式与xml解析的方法基本没有什么区别,我们首先要定义一个结构体,然后调用json.Unmarshal把数据解析到结构体:
func StructMethod() {
resp := `{"code": "00",
"message": "SUCCESS",
"describe": "成功",
"resultInfo": { "uniqueNumber": "201808161133401673324075025000035" }
}`
type JsonResp struct {
Code int `json:"code"`
Message string `json:"message"`
Describe string `json:"describe"`
ResultInfo map[string]string `json:"resultInfo"`
}
var smsresp JsonResp
temp := []byte(resp)
errs := json.Unmarshal(temp, &smsresp)
if errs != nil {
return
}
fmt.Println(smsresp.Code)
fmt.Println(smsresp.Describe)
fmt.Println(smsresp.Message)
fmt.Println(smsresp.ResultInfo["uniqueNumber"])
}
json数据与struct字段是如何相匹配的呢?
可能有的小伙伴和我一样好奇,在解析的时候,json数据与struct字段是如何相匹配的呢?例如JSON的key是code,那么怎么找对应的字段呢?
- 首先查找tag含有code的可导出的struct字段(首字母大写)
- 其次查找字段名是code的导出字段
- 最后查找类似Code或者COde这样的除了首字母之外其他大小写不敏感的导出字段
注意: 能够被赋值的字段必须是可导出字段(即首字母大写)。同时JSON解析的时候只会解析能找得到的字段,找不到的字段会被忽略。我们在实际使用的过程中一定要随时警惕这一点。
其实与这个潜在的坑相比,它的优势非常明显:当你接收到一个很大的JSON数据结构而你却只想获取其中的部分数据的时候,你只需将你想要的数据对应的字段名大写,即可轻松解决。
解析到interface
上面那种解析方式是在我们知晓被解析的JSON数据的结构的前提下采取的方案,如果我们不知道被解析的数据的格式,又应该如何来解析呢?
Go类型和JSON类型
我们知道interface{}可以用来存储任意数据类型的对象,这种数据结构正好用于存储解析的未知结构的json数据的结果。JSON包中采用map[string]interface{}和[]interface{}结构来存储任意的JSON对象和数组。Go类型和JSON类型的对应关系如下:
| 类型 | JSON类型 |
|---|---|
| bool | JSON booleans, |
| float64 | JSON numbers, |
| string | JSON strings, |
| nil | JSON null. |
实例代码
// InterfaceMethod 方式
func InterfaceMethod() {
resp := `{"code": "00",
"message": "SUCCESS",
"describe": "成功",
"resultInfo": {"uniqueNumber": "201808161133401673324075025000035"}
}`
var x interface{}
_ = json.Unmarshal([]byte(resp), &x)
m := x.(map[string]interface{})
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case float64:
fmt.Println(k, "is float64", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
case map[string]interface{}:
fmt.Println(k, "is an map[string]string:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type didn't handle")
}
}
}
simpleJson
上面两种方式其实已经能应付我们一般的工作了,但是单纯就解析数据而言(这里先买个关子),其实还有一种更简单的方式,那就是第三方库:github.com/bitly/go-simplejson,使用方法如下:
func SimplejsonMethod() {
resp := `{"code": "00",
"message": "SUCCESS",
"describe": "成功",
"resultInfo": { "uniqueNumber": "201808161133401673324075025000035" }
}`
js, errs := NewJson([]byte(resp))
if errs != nil {
return
}
discount := js.Get("resultInfo").Get("uniqueNumber")
strcode, _ := js.Get("code").String()
intcode, _ := js.Get("code").Int()
path := js.GetPath("resultInfo", "uniqueNumber")
fmt.Println(discount)
fmt.Println(strcode)
fmt.Println(intcode)
fmt.Println(path)
}
运行输出:
bingo@Mac unpackData$ go run JSONparse.go
&{201808161133401673324075025000035}
00
0
&{201808161133401673324075025000035}
GetPath方法是Get的人精简版,使用结尾调用的方法可以吧输出的结果转化为指定的类型(string 00 转换为 0 )。
那么多个方法的调用怎么完成数据传递的呢?输出结果的&符号其实已经暴露了它的身份,对就是指针,这个库每个方法接收和返回的都是指针数据。
总结
- json 解析 到struct
- interface{}与type assert的配合使用
- simplejson
- 学习一门语言是一个慢慢熟悉的过程,初始是不易使用完成度太高的轮子
【Golang 接口自动化04】 解析接口返回JSON串的更多相关文章
- spring入门(七)【springMVC返回json串】
现在多数的应用为了提高交互性多使用异步刷新,即在不刷新整个页面的情况下,只刷新局部,局部刷新用得最多就是ajax,ajax和后台进行交互的数据格式使用的最多的是JSON,这里简单描述,在springm ...
- Python3.x:访问带参数链接并且获取返回json串
Python3.x:访问带参数链接并且获取返回json串 示例一: import json import xml.dom.minidom from urllib import request, par ...
- springmvc 1.接受日期类型的参数 2.后台返回json串的格式处理(返回json串null值处理为"")
springmvc中的配置: <bean id="dateConvert" class="com.iomp.util.DateConvert"/> ...
- python接口自动化(十九)--Json 数据处理---实战(详解)
简介 上一篇说了关于json数据处理,是为了断言方便,这篇就带各位小伙伴实战一下.首先捋一下思路,然后根据思路一步一步的去实现和实战,不要一开始就盲目的动手和无头苍蝇一样到处乱撞,撞得头破血流后而放弃 ...
- python接口自动化24-有token的接口项目使用unittest框架设计
获取token 在做接口自动化的时候,经常会遇到多个用例需要用同一个参数token,并且这些测试用例跨.py脚本了. 一般token只需要获取一次就行了,然后其它使用unittest框架的测试用例全部 ...
- python接口自动化根据请求接口类型进行封装
根据不同的请求类型(GET/POST)进行接口请求封装 import requests import json class RunMain: def __init__(self, url, metho ...
- spring 4.x下让http请求返回json串
当前很多应用已经开始将响应返回为json串,所以基于springframework框架开发的服务端程序,让响应返回json字符串成为了一种常用手段. 这里介绍一下如何在spring-MVC框架下方便快 ...
- 接口自动化(三)--读取json文件中的数据
上篇讲到实际的请求数据放置在json文件内,这一部分记述一下python读取json文件的实现. 代码如下(代码做了简化,根据需要调优:可做一些容错处理): 1 import json 2 3 cla ...
- python接口自动化:响应内容中json字符串对象的处理
实现代码如下: import json #定义一个字典.一个列表.两个字符串({}中必须是双引号) di1={"} di2=[{"}] di3='{"name" ...
随机推荐
- 一个新人对HTML内JavaScript的理解
首先是对于JavaScript(以后简称JS)的定义: ① JS他是一个脚本语言,有点类似于外部插件,需要插入引用才会有效 ② 他需要一个宿主文件,就是他插入到谁里面进行运算,谁就是这个JS的宿主文件 ...
- 远程桌面时出现身份验证错误,要求的函数不正确,这可能是由于CredSSP加密Oracle修正
问题如下: 那么解决办法如下:
- webp格式
有时候你右键保存了一张图片,然后好气啊,打不开.这要么是webp格式,要么,,,,要么有问题啊. WebP格式,谷歌大法开发的一种旨在加快图片加载速度的图片格式.图片压缩体积大约只有JPEG的2/3, ...
- 浅谈css中渐变衔接
无论transition还是keyframes,如何让变化更自然,这是前端应该考虑的问题. 这里,我简单总结下自己的方法. 以实践为例子. 1.图像渐变 @keyframes looppic{ fro ...
- 限制 input 输入框只能输入纯数字
oninput = "value=value.replace(/[^\d]/g,'')"
- PDF常见问题总结
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...
- PHP读取sphinx 搜索返回结果完整实战实例
PHP读取sphinx 搜索返回结果完整实战实例 网上搜索N久都没有一个正在读取返回sphinx结果的实例,都是到了matches那里就直接var_dump或者print_r了,没有读取到字段的例子, ...
- PHP empty、isset、isnull的区别
PHP empty.isset.isnull的区别 empty 如果 变量 是非空或非零的值,则 empty() 返回 FALSE.换句话说,”".0.”0″.NULL.FALSE.arra ...
- JavaScript中几种 获取元素的方式
1.根据id获取元素 document.getElementById("id属性的值"); 2.根据标签名字获取元素 document.getElementsByTagName(& ...
- Windows下MongoDB安装
1.解压mongodb-win32-i386-1.8.1.zip ,创建路径d:\mongodb ,将解压后的Bin文件Copy to 此文件夹下 2.d:\mongodb 下建立Data文件夹 d: ...