最近一直再思考统一网易云音乐与qq音乐的api,做着做着写了好多代码
利用 linux的 tree -if 命令,展示一下这几天写的代码

root@angel:~# tree -if starter/
starter
starter/annotation
starter/annotation/BiAsyncAnnotaion.java
starter/annotation/MusicService.java
starter/configuration
starter/configuration/properties
starter/configuration/properties/YumbMusicServiceProperties.java
starter/configuration/properties/YumboMusicServiceNeteaseProperties.java
starter/configuration/properties/YumboMusicServiceQQProperties.java
starter/configuration/properties/YumboThreadPoolProperties.java
starter/configuration/YumboMusicAutoConfiguration.java
starter/configuration/YumboThreadPoolExecuterAutoConfiguration.java
starter/controller
starter/controller/MusicController.java
starter/controller/MVController.java
starter/controller/UserController.java
starter/entity
starter/entity/abstractMusic
starter/entity/abstractMusic/AbstractMusic.java
starter/entity/abstractMusic/AbstractYumboMusic.java
starter/entity/abstractMusic/AbstractYumboMV.java
starter/entity/netease
starter/entity/netease/NeteaseCloudMusicInfo.java
starter/entity/netease/NeteaseMusic.java
starter/entity/netease/NeteaseMV.java
starter/entity/otherMusic
starter/entity/otherMusic/OtherMusicInfo.java
starter/entity/qq
starter/entity/qq/QQMusicInfo.java
starter/entity/qq/QQMusic.java
starter/entity/qq/QQMV.java
starter/entity/Singer.java
starter/entity/yumboEnum
starter/entity/yumboEnum/MusicBitRateEnum.java
starter/entity/yumboEnum/MusicEnum.java
starter/entity/yumboEnum/MVBitRateEnum.java
starter/entity/yumboEnum/SearchTypeEnum.java
starter/entity/YumboMusic.java
starter/service
starter/service/YumboCommonService.java
starter/service/YumboMusicService.java
starter/service/YumboMVService.java
starter/SpringBootStarterMusicApplication.java
starter/utils
starter/utils/BiAsyncRequestUtils.java
starter/utils/JsonCombineUtils.java
starter/utils/YumboMusicRequestUtils.java12 directories, 34 files
root@angel:~# ls -lh starter
total 28K
drwxr-xr-x 2 root root 4.0K Jan 15 22:19 annotation
drwxr-xr-x 3 root root 4.0K Jan 15 22:19 configuration
drwxr-xr-x 2 root root 4.0K Jan 15 22:19 controller
drwxr-xr-x 7 root root 4.0K Jan 15 22:19 entity
drwxr-xr-x 2 root root 4.0K Jan 15 22:19 service
-rw-r--r-- 1 root root  361 Jan 15 22:19 SpringBootStarterMusicApplication.java
drwxr-xr-x 2 root root 4.0K Jan 15 22:19 utils

  边写边思考问题,因为我想把两个音乐的api数据合成一个数据(会遇到 字段映射,多余字段,新增字段,字段之间的计数等问题)。在处理这些从网易云音乐api服务器和qq音乐服务器返回的json数据时,起初我是直接使用fastjson的get、put、parse、to这些方法来做转换和计算。

  当我做了几个接口后,感觉这样一直在做重复且无聊的事情,我在思考更优的解决方法。比如模仿springbootyml的使用,通过配置达到想要的功能,将json的转换规则进行解耦(不和代码直接绑定)。目的是做一个通用的工具,然后配置规则就能得到转换后的 json

  经过自己的思考过后,打算尝试自己做一个工具,完成我想要的功能,于是就开始了设计规则

下面的json字符串是模板数据,也就是需要返回的数据字段的定义

  1. type表示字段的类型
  2. note则是说明
  3. weight表示权重
  4. count表示需要进行计算的表达式
  5. template则是模板数据(每一个字段对应数据的json结构)
{"total": {"type": "int","note": "所有歌曲的总数","weight": 1,"count": "qq.data.total + netease.result.songCount"},"qq": {"type": "int","note": "songs中来自qq音乐的条数","weight": 2,"count": "qq.songs[length]"},"netease": {"type": "int","note": "songs中来自网易云音乐的条数","weight": 2,"count": "netease.songs[length]"},"return_back": {"type": "int","note": "当前返回的总条数","weight": 3,"count": "this.qq + this.netease"},"template": {"name": "songs","type": "array"},"songs": [{"type": "qq","songName": "json.data.list[].songname","albumName": "json.data.list[].albumname","durationTime": "json.data.list[].interval","musicId": "json.data.list[].songmid","singer": [{"name": "json.data.list[].singer.name","id": "json.data.list[].singer.id"}],"mvId": "json.data.list[].vid","albumId": "json.data.list[].albummid"},{"type": "netease","songName": "json.result.songs[].name","albumName": "json.result.songs[].album.name","durationTime": "json.result.songs[].duration","musicId": "json.result.songs[].id","singer": [{"name": "json.result.songs[].artists[].name","id": "json.result.songs[].artists[].id"}],"mvId": "json.result.songs[].mvid","albumId": "json.result.songs[].album.id"}]
}

  在处理并形成符合模板数据的过程中,我用到了fastjson中的JsonArray对象,在做遍历的时候,我在思考是java8的forEach方法遍历快还是通过get 索引更快,于是搜索了一下fastjson,于是找到了JsonPath


  发现json-path已经做了我想要做的事情,那么我就打算借用json-path快速的将网易云音乐,qq音乐的api进行统一。只要定义好路径可以快速的提取自己需要的信息。
当然Fastjson也提供了json-path语法,搜索资料经过再三考虑决定使用Fastjson


以下内容来自github的文档,可以直接点击下面的文档地址


JSONPath文档地址(fastjson)

https://github.com/alibaba/fastjson/wiki/JSONPath

第一步、pom中引入fastjson

建议使用最新版的,我在引入的时候fastjson的版本是1.2.75
fastjson的maven仓库地址

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version>
</dependency>

JsonPath语法

语法 作用
$ 根对象,例如$.name
[num] 数组访问,其中num是数字,可以是负数。
例如$[0].leader.departments[-1].name
[num0,num1,num2...] 数组多个元素访问,其中num是数字,可以是负数,返回数组中的多个元素。例如$[0,3,-2,5]
[start:end] 数组范围访问,其中start和end是开始小表和结束下标,可以是负数,返回数组中的多个元素。例如$[0:5]
[start:end :step] 数组范围访问,其中startend是开始小表和结束下标,可以是负数;
step是步长,返回数组中的多个元素。例如$[0:5:2]
[?(key)] 对象属性非空过滤,例如$.departs[?(name)]
[key > 123] 数值类型对象属性比较过滤,例如$.departs[id >= 123],比较操作符支持=,!=,>,>=,<,<=
[key = ‘123’] 字符串类型对象属性比较过滤,例如$.departs[name = '123'],比较操作符支持=,!=,>,>=,<,<=
[key like ‘aa%’] 字符串类型like过滤,例如$.departs[name like 'sz*']
通配符只支持 %
支持 not like
[key rlike ‘regexpr’] 字符串类型正则匹配过滤,例如 departs[name like 'aa(.)*'],正则语法为jdk的正则语法,支持 not rlike
[key in (‘v0’, ‘v1’)] IN过滤, 支持字符串和数值类型。
例如:$.departs[name in ('wenshao','Yako')]
$.departs[id not in (101,102)]
[key between 234 and 456] BETWEEN过滤, 支持数值类型,支持not between
例如:$.departs[ id between 101 and 201]
$.departs[ id not between 101 and 201]
length() 或者 size() 数组长度
例如 $.values.size()支持类型 java.util.Map 和 java.util.Collection 和数组
keySet() 获取Map的 keySet 或者对象的非空属性名称。例如$.val.keySet()
支持类型:Map 和 普通对象
不支持:Collection和数组(返回null)
. 属性访问,例如$.name
.. deepScan属性访问,例如$..name
* 对象的所有属性,例如$.leader.*
['key'] 属性访问。例如$['name']
['key0','key1'] 多个属性访问。例如$['id','name']

下面两种写法的语义相同

$.store.book[0].title

$['store']['book'][0]['title']

语法示例

JSONPath 语义
$ 根对象
$[-1] 最后元素
$[:-2] 第1个至倒数第2个
$[1:] 第2个之后所有元素
$[1,2,3] 集合中1,2,3个元素

第二步、根据语法以及实际中的json数据编写jsonpath

jsonString是json字符串,jsonpath则是定义的path规则

String jsonpath="$.store.book[0:3]";// 定义规则
final Object read = JSONPath.read(jsonString, jsonpath);// 进行解析
final String s = JSONObject.toJSONString(read);// 将对象转换成字符串

public static class Entity {private Integer id;private String name;private Object value;public Entity() {}public Entity(Integer id, Object value) { this.id = id; this.value = value; }public Entity(Integer id, String name) { this.id = id; this.name = name; }public Entity(String name) { this.name = name; }public Integer getId() { return id; }public Object getValue() { return value; }        public String getName() { return name; }public void setId(Integer id) { this.id = id; }public void setName(String name) { this.name = name; }public void setValue(Object value) { this.value = value; }
}

例1

读取集合多个元素的某个属性

List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity("wenshao"));
entities.add(new Entity("ljw2083"));// 返回enties的所有名称
List<String> names = (List<String>)JSONPath.eval(entities, "$.name");

例2

返回集合中多个元素

List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity("wenshao"));
entities.add(new Entity("ljw2083"));
entities.add(new Entity("Yako"));// 返回下标为1和2的元素
List<Entity> result = (List<Entity>)JSONPath.eval(entities, "[1,2]");

例3

按范围返回集合的子集

List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity("wenshao"));
entities.add(new Entity("ljw2083"));
entities.add(new Entity("Yako"));// 返回下标从0到2的元素
List<Entity> result = (List<Entity>)JSONPath.eval(entities, "[0:2]");

例4

通过条件过滤,返回集合的子集

List<Entity> entities = new ArrayList<Entity>();
entities.add(new Entity(1001, "ljw2083"));
entities.add(new Entity(1002, "wenshao"));
entities.add(new Entity(1003, "yakolee"));
entities.add(new Entity(1004, null));List<Object> result = (List<Object>) JSONPath.eval(entities, "[id in (1001)]");

例5

根据属性值过滤条件判断是否返回对象,修改对象,数组属性添加元素

Entity entity = new Entity(1001, "ljw2083");JSONPath.set(entity, "id", 123456); //将id字段修改为123456
JSONPath.set(entity, "value", new int[0]); //将value字段赋值为长度为0的数组
JSONPath.arrayAdd(entity, "value", 1, 2, 3); //将value字段的数组添加元素1,2,3

例6 keySet

使用keySet抽取对象的属性名,null值属性的名字并不包含在keySet结果中,使用时需要注意,详细可参考示例。

Entity e = new Entity();
e.setId(null);
e.setName("hello");
Map<String, Entity> map = Collections.singletonMap("e", e);
Collection<String> result;// id is null, excluded by keySet
result = (Collection<String>)JSONPath.eval(map, "$.e.keySet()");// result.seze()=1e.setId(1L);
result = (Collection<String>)JSONPath.eval(map, "$.e.keySet()");// result.seze()=2,因为id不为null,所以keySet()返回的就是id,name两个

JSONPath的语法和使用相关推荐

  1. python中path语句什么意思_python中jsonpath模块有何用法?

    小编做项目的时候,遇到一个问题,虽然解决了,但是也是深入的思考的一番,遇到问题是这样的,我们返回的基本格式都是json,但是json都是层层递进的,如果想审核json中心找到字符串等内容,要一层一层的 ...

  2. python的jsonpath_python 提取json数据的jsonPath介绍及简单使用

    为什么要用jsonpath 就跟为什么要用xpath一样,jsonpath的设计灵感来源于xpath.一个强大的json数据提取工具.让用户不用编写脚本就可以提取到相应的json数据. jsonpat ...

  3. python接口测试非json的断言_荐在接口自动化测试中,如何利用Pytest + JSONPath 进行接口响应断言...

    之前有一篇文章,介绍了如何使用JSONSchema对接口响应进行断言,主要的适用场景是对响应的数据结构进行校验,保证客户端收到的数据结构稳定和合法.今天,介绍使用JSONPath对接口响应的值进行断言 ...

  4. python-json校验-jsonpath

    本文为在霍格沃兹测试开发学社中学习到的一些技术,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 霍格沃兹启发 技术分享 | 接口自动化测试如何搞定 json 响应断言? 背景 在 ...

  5. python jsonpath模块

    jsonpath jsonpath第三方模块.jsonpath是json的XPath工具,简单说就是从 字典对象 中查找数据更方便,可以解析多层嵌套的json数据. 不使用jsonpath时查询 字典 ...

  6. 在接口自动化测试中,如何利用Pytest + JSONPath 进行接口响应断言

    之前有一篇文章,介绍了如何使用JSONSchema对接口响应进行断言,主要的适用场景是对响应的数据结构进行校验,保证客户端收到的数据结构稳定和合法.今天,介绍使用JSONPath对接口响应的值进行断言 ...

  7. JSON解析工具----JSONPath基本使用

    转自:作者:琴水玉 https://www.cnblogs.com/lovesqcc/p/7821641.html JsonPath:从多层嵌套Json中解析所需要的值 问题 基本方案 JsonPat ...

  8. python编辑工具——jsonpath在线解析工具

    每天进步一点点,关注我们哦,每天分享测试技术文章 本文章出自[码同学软件测试] 码同学公众号:自动化软件测试 码同学抖音号:小码哥聊软件测试 01 Jsonpath的定义 JsonPath是一种简单的 ...

  9. JsonPath用法详解

    JSONPath是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括Javascript.Python.PHP和Java. JSONPath的安装方法如下: pip i ...

最新文章

  1. pygame 移开的矩形留痕迹_Python之pygame学习矩形区域(5)
  2. 数据增删改查之三层架构(理解三层续)
  3. A - 数据结构实验之排序一:一趟快排
  4. 睡觉前后爆笑的情侣小两口~媳妇不要闹了~
  5. HDU 12O3 I NEED A OFFER!
  6. 用Python爬取漫画并转换格式为pdf和mobi
  7. Chrome浏览器启动参数大全(命令行参数)
  8. c语言printf输出格式
  9. 国内外各大搜索引擎登录入口
  10. 小程序提示 网络异常 Network Anomalies
  11. android蓝牙同步拨打电话状态,还不会用华为Watch打电话?这六个步骤要记清!
  12. 【原理分析】Google炫炸天的平衡自行车仅仅是概念吗?来看看惯性轮自行车吧...
  13. 常见的DNS攻击与相应的防御措施
  14. 高阶多项式合并同类项程序c语言,c语言实现两多项式相乘,并排序,合并同类项.doc...
  15. 中国学生常见的英文论文写作问题
  16. 0月租注册卡,2019助力公司发展新篇章
  17. 开放共赢 平安云AI生态合作开启
  18. 日复一日 - C++ (设计符合下述要求的日期类(Date))新人
  19. 庄思浩先生在清华大学的演讲(2002)
  20. node.js源码编译安装(linux)

热门文章

  1. java动态设置定时任务
  2. 从硬盘安装Linux操作系统的方法步骤
  3. request.getParameterMap()
  4. 计算机组成原理移位运算实验报告,移位运算器实验报告.doc
  5. Windows2008R2 多用户同时远程登录服务器
  6. SQL severe 存储过程例题
  7. 中国体外冲击波碎石机行业市场供需与战略研究报告
  8. linux RMP软件包 rpm管理
  9. Http get方式发送请求
  10. Linux中级运维工程师面试题及答案