【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" ...
随机推荐
- svg绘图工具raphael.js的使用
1.raphael.js svg画图的开源库,支持IE8+ 官方api: http://dmitrybaranovskiy.github.io/raphael/reference.html Githu ...
- javascript利用jquery-1.7.1来判断是否是谷歌Chrome浏览器
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" con ...
- Bus,Exclusive access,memory attribute
指令LDREX,STREX是在armv6中新加的指令,配合AMBA3--AXI中的lock[1:0]信号. 在Atomic Access一节中是这么规定的:ARLOCK[1:0]/AWLOCK[1:0 ...
- form表单提交 type="submit"
<form action="" method="post" onsubmit="return validte()"> < ...
- UVA10066
/* 最长公共子序列 */ #include <cstdio> #include <string.h> #include <iostream> const int ...
- Linux下的Make命令实例详解
众所周知在Linux系统下的make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.下面这 篇文章我们将用一 ...
- python堆排序
堆是完全二叉树 子树是不相交的 度 节点拥有子树的个数 满二叉树: 每个节点上都有子节点(除了叶子节点) 完全二叉树: 叶子结点在倒数第一层和第二层,最下层的叶子结点集中在树的左部 ,在右边的话,左子 ...
- centos7.3上安装oracle xe 11g
oracle -11g-xe是数据库是免费版本,支持标准版的大部分功能.oracle XE版本也称快捷版本.是个个人学习,熟悉oracle的简化版. oracle XE做为免费的Oracle数据库版本 ...
- Linux基础命令---mkisofs
mkisofs mkisofs指令可以创建ISO9660/Joliet/HFS文件系统,现在使用指令genisoimage代替它.genisoImage是一个预掌握程序,用于生成iso 9660/jo ...
- 2D 2 3D 开源项目
http://www.cvlibs.net/projects.php http://www.cvlibs.net/software/libelas/