iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >如何正确的使用 jsonpath
  • 243
分享到

如何正确的使用 jsonpath

2023-06-06 11:06:36 243人浏览 泡泡鱼
摘要

今天就跟大家聊聊有关如何正确的使用 JSONpath,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。java项目demo:注意: 其中他的max,min,avg,stddev函数只能类

今天就跟大家聊聊有关如何正确的使用 JSONpath,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

java项目demo:

如何正确的使用 jsonpath

注意: 其中他的max,min,avg,stddev函数只能类似于如下处理:

//正确写法 但是感觉很鸡肋context.read("$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)");

不能传入list 感觉比较鸡肋,如果传入list 他会报错(如下错误写法):

//这样会报错Object maxV = context.read("$.max($.result.records[*].loan_type)");//这样也会报错Object maxV = context.read("$.result.records[*].loan_type.max()");//如果json文件中是这样:"loan_type":"2",也会报错,"loan_type":2 这样才被认为是数字

报错信息都一样, 如下:

Exception in thread "main" com.jayway.jsonpath.JsonPathException: Aggregation function attempted to calculate value using empty array

JsonPathDemo是一个测试demo:

public class JsonPathDemo { public static void main(String[] args) { String json = FileUtils.readFileByLines("demo.json"); ReadContext context = JsonPath.parse(json); //1 返回所有name List<String> names = context.read("$.result.records[*].name"); //["张三","李四","王五"] System.out.println(names); //2 返回所有数组的值 List<Map<String, String>> objs = context.read("$.result.records[*]"); //[{"name":"张三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"},{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3","all":"3"},{"name":"王五","pid":"50023415464654659","mobile":"1706454894","applied_at":"-1","confirmed_at":"","confirm_type":"overdue","loan_type":"3"}] System.out.println(objs); //3 返回第一个的name String name0 = context.read("$.result.records[0].name"); //张三 System.out.println(name0); //4 返回下标为0 和 2 的数组值 List<String> name0and2 = context.read("$.result.records[0,2].name"); //["张三","王五"] System.out.println(name0and2); //5 返回下标为0 到 下标为1的 的数组值 这里[0:2] 表示包含0 但是 不包含2 List<String> name0to2 = context.read("$.result.records[0:2].name"); //["张三","李四"] System.out.println(name0to2); //6 返回数组的最后两个值 List<String> lastTwoName = context.read("$.result.records[-2:].name"); //["李四","王五"] System.out.println(lastTwoName); //7 返回下标为1之后的所有数组值 包含下标为1的 List<String> nameFromOne = context.read("$.result.records[1:].name"); //["李四","王五"] System.out.println(nameFromOne); //8 返回下标为3之前的所有数组值 不包含下标为3的 List<String> nameEndTwo = context.read("$.result.records[:3].name"); //["张三","李四","王五"] System.out.println(nameEndTwo); //9 返回applied_at大于等于2的值 List<Map<String, String>> records = context.read("$.result.records[?(@.applied_at >= '2')]"); //[{"name":"张三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"}] System.out.println(records); //10 返回name等于李四的值 List<Map<String, String>> records0 = context.read("$.result.records[?(@.name == '李四')]"); //[{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3"}] System.out.println(records0); //11 返回有test属性的数组 List<Map<String, String>> records1 = context.read("$.result.records[?(@.test)]"); //[{"name":"张三","pid":"500234199212121212","mobile":"18623456789","applied_at":"3","confirmed_at":"5","confirm_type":"overdue","loan_type":"1","test":"mytest","all":"2"}] System.out.println(records1); //12 返回有test属性的数组 List<String> list = context.read("$..all"); //["1","4","2","3"] System.out.println(list); //12 以当前json的某个值为条件查询 这里ok为1 取出records数组中applied_at等于1的数组 List<String> ok = context.read("$.result.records[?(@.applied_at == $['ok'])]"); //["1","4","2","3"] System.out.println(ok); //13 正则匹配 List<String> regexName = context.read("$.result.records[?(@.pid =~ /.*999/i)]"); //[{"name":"李四","pid":"500234199299999999","mobile":"13098765432","applied_at":"1","confirmed_at":"","confirm_type":"overdue","loan_type":"3","all":"3"}] System.out.println(regexName); //14 多条件 List<String> mobile = context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].mobile"); //["18623456789","13098765432"] System.out.println(mobile); //14 查询数组长度 Integer length01 = context.read("$.result.records.length()"); //3 System.out.println(length01); //15 查询list里面每个对象长度 List<Integer> length02 = context.read("$.result.records[?(@.all == '2' || @.name == '李四' )].length()"); //[9,8] System.out.println(length02); //16 最大值 Object maxV = context.read("$.max($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //3.0 System.out.println(maxV); //17 最小值 Object minV = context.read("$.min($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //1.0 System.out.println(minV); //18 平均值 double avgV = context.read("$.avg($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //2.3333333333333335 System.out.println(avgV); //19 标准差 double stddevV = context.read("$.stddev($.result.records[0].loan_type,$.result.records[1].loan_type,$.result.records[2].loan_type)"); //0.9428090415820636 System.out.println(stddevV); //20 读取一个不存在的 String haha = context.read("$.result.haha"); //抛出异常 //Exception in thread "main" com.jayway.jsonpath.PathNotFoundException: No results for path: $['result']['haha'] //at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133) //at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187) //at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102) //at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:89) //at cn.lijie.jsonpath.JsonPathDemo.main(JsonPathDemo.java:58) //at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) //at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) //at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) //at java.lang.reflect.Method.invoke(Method.java:498) //at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) System.out.println(haha); }}

pom文件引入:

 <dependency>  <groupId>com.jayway.jsonpath</groupId>  <artifactId>json-path</artifactId>  <version>2.3.0</version> </dependency>

其中demo.json是一个测试json:

{ "action": "/interface.service/xxx/queryBlackUserData", "all": "1", "result": { "count": 2, "tenant_count": 2, "records": [ { "name": "张三", "pid": "500234199212121212", "mobile": "18623456789", "applied_at": "3", "confirmed_at": "5", "confirm_type": "overdue", "loan_type": 1, "test": "mytest", "all": "2" }, { "name": "李四", "pid": "500234199299999999", "mobile": "13098765432", "applied_at": "1", "confirmed_at": "", "confirm_type": "overdue", "loan_type": 3, "all": "3" }, { "name": "王五", "pid": "50023415464654659", "mobile": "1706454894", "applied_at": "-1", "confirmed_at": "", "confirm_type": "overdue", "loan_type": 3 } ], "all": "4" }, "code": 200, "subtime": "1480495123550", "status": "success", "ok": 3}

FileUtils类是用于读取xx.json文件为字符串的json:

public class FileUtils {  public static String readFileByLines(String fileName) { File file = new File(fileName); BufferedReader reader = null; String str = ""; try {  InputStream is = FileUtils.class.getClassLoader().getResourceAsStream(fileName);  reader = new BufferedReader(new InputStreamReader(is));  String tempString = null;  int line = 1;  // 一次读入一行,直到读入null为文件结束  while ((tempString = reader.readLine()) != null) {  // 显示行号  str += tempString;  }  reader.close(); } catch (IOException e) {  e.printStackTrace(); } finally {  if (reader != null) {  try {   reader.close();  } catch (IOException e1) {  }  } } return str; }}

补充:json接口测试的利器jsonpath

在测试REST接口的时候,经常要解析JSON,那么可以使用开源jsonpath进行,其中看网上看到相关的说法不错的使用场景为:

1、接口关联

也称为关联参数。在应用业务接口中,完成一个业务功能时,有时候一个接口可能不满足业务的整个流程逻辑,需要多个接口配合使用,简单的案例如:B接口的成功调用依赖于A接口,需要在A接口的响应数据(response)中拿到需要的字段,在调用B接口的时候,传递给B接口作为B接口请求参数,拿到后续响应的响应数据。

接口关联通常可以使用正则表达式去提取需要的数据,但对于json这种简洁、清晰层次结构、轻量级的数据交互格式,使用正则未免有点杀鸡用牛刀的感觉(是的,因为我不擅长写正则表达式),我们需要更加简单、直接的提取json数据的方式。

2、数据验证

这里的数据验证指的是对响应结果进行数据的校验

接口自动化测试中,对于简单的响应结果(json),可以直接和期望结果进行比对,判断是否完全相等即可。

如 json {"status":1,"msg":"登录成功"}

3、对于格式较复杂

尤其部分数据存在不确定性、会根据实际情况变化的响应结果,简单的判断是否完全相等(断言)通常会失败。

如:

json {"status":1,"code":"10001","data":[{"id":1,"investId":"1","createTime":"2018-04-27 12:24:01","terms":"1","unfinishedInterest":"1.0","unfinishedPrincipal":"0","repaymentDate":"2018-05-27 12:24:01","actualRepaymentDate":null,"status":"0"},{"id":2,"investId":"1","createTime":"2018-04-27 12:24:01","terms":"2","unfinishedInterest":"1.0","unfinishedPrincipal":"0","repaymentDate":"2018-06-27 12:24:01","actualRepaymentDate":null,"status":"0"},{"id":3,"investId":"1","createTime":"2018-04-27 12:24:01","terms":"3","unfinishedInterest":"1.0","unfinishedPrincipal":"100.00","repaymentDate":"2018-07-27 12:24:01","actualRepaymentDate":null,"status":"0"}],"msg":"获取信息成功"}

上面的json结构嵌套了很多信息,完整的匹配几乎不可能成功。比如其中的createTime信息,根据执行接口测试用例的时间每次都不一样。同时这个时间是响应结果中较为次要的信息,在进行接口自动化测试时,是可以选择被忽略的。

4、我们需要某种简单的方法

能够从json中提取出我们真正关注的信息(通常也被称为关键信息)。

如提取出status的值为1,data数组中每个对象的investId都为1,data中第三个对象的unfinishedPrincipal值为100.00,只要这三个关键信息校验通过,我们就认为响应结果没有问题。

JSONPATH有点像XPATH了,语法规则小结下:

这里有个表格,说明JSONPath语法元素和对应XPath元素的对比。

XPathJSONPathDescription
/$表示根元素
.@当前元素
/. or []子元素
..n/a父元素
//..递归下降,JSONPath是从E4X借鉴的。
**通配符,表示所有的元素
@n/a属性访问字符
[][]

子元素操作符

|[,]

连接操作符在XPath 结果合并其它结点集合。JSONP允许name或者数组索引

n/a[start:end:step]

数组分割操作从ES4借鉴。

[]?()

应用过滤表示式

n/a()

脚本表达式,使用在脚本引擎下面。

()n/aXpath分组

下面是一个简单的json数据结构代表一个书店(原始的xml文件是)

{ "store": { "book": [  { "cateGory": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "SWord of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } }}
XPathJSONPath结果
/store/book/author$.store.book[*].author

书点所有书的作者

//author$..author

所有的作者

/store //article : jsonpath in array @Test public void save_emptyAuthor_emptyPrice_400() throws Exception {  String bookInJson = "{\"name\":\"ABC\"}";  mockmvc.perfORM(post("/books")  .content(bookInJson)  .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON))  .andDo(print())  .andExpect(status().isBadRequest())  .andExpect(jsonPath("$.timestamp", is(notNullValue())))  .andExpect(jsonPath("$.status", is(400)))  .andExpect(jsonPath("$.errors").isArray())  .andExpect(jsonPath("$.errors", hasSize(3)))  .andExpect(jsonPath("$.errors", hasItem("Author is not allowed.")))  .andExpect(jsonPath("$.errors", hasItem("Please provide a author")))  .andExpect(jsonPath("$.errors", hasItem("Please provide a price")));  verify(mockRepository, times(0)).save(any(Book.class));  }}

看完上述内容,你们对如何正确的使用 jsonpath有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

--结束END--

本文标题: 如何正确的使用 jsonpath

本文链接: https://www.lsjlt.com/news/246544.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何正确的使用 jsonpath
    今天就跟大家聊聊有关如何正确的使用 jsonpath,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。java项目demo:注意: 其中他的max,min,avg,stddev函数只能类...
    99+
    2023-06-06
  • 如何正确的使用WeakHashMap
    这篇文章给大家介绍如何正确的使用WeakHashMap,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 在学习WeakHashMap时了解到,如果map里面的key只有map本身引用时,就会将key对应的Entry清除掉...
    99+
    2023-05-30
    weakhashmap
  • 如何正确的使用JDBC
    今天就跟大家聊聊有关 如何正确的使用JDBC,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。什么是JDBCJDBC(Java Database Connectivity),即Java数...
    99+
    2023-05-31
    jdbc jdb
  • 如何正确的使用supervisor
    这期内容当中小编将会给大家带来有关如何正确的使用supervisor,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。软硬件环境centos7.6.1810 64bitcat /etc/redhat...
    99+
    2023-06-06
  • 如何正确的使用JAXB
    这期内容当中小编将会给大家带来有关如何正确的使用JAXB,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、jaxb是什么     JAXB是Java Archite...
    99+
    2023-05-31
    jaxb
  • 如何正确的使用TypeScript
    如何正确的使用TypeScript,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、TypeScript 是什么TypeScript 是一种由微软开发的自由和开源的编程语言...
    99+
    2023-06-17
  • 如何正确的使用Puppet
    今天就跟大家聊聊有关如何正确的使用Puppet,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1. 概述 puppet是一个开源的软件自动化配置和部署工具,它使用简单且功能强大,正得到...
    99+
    2023-06-12
  • 如何正确的使用pytest
    本篇文章为大家展示了如何正确的使用pytest,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、安装pytest,打开dos窗口输入:pip install pytest2、通过pycharm工具下...
    99+
    2023-06-07
  • 如何正确的使用CMake
    如何正确的使用CMake?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makef...
    99+
    2023-06-08
  • 如何正确的使用numpy.sum()
    这篇文章给大家介绍如何正确的使用numpy.sum(),内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。numpy的sum函数可接受的参数是:sum(a, axis=None, dtype=None,&...
    99+
    2023-06-15
  • 如何正确的使用Gradle
    本篇文章为大家展示了如何正确的使用Gradle,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、Gradle相比Maven的优势配置简洁Maven是用pom.xml管理,引入一个jar包至少5行代码...
    99+
    2023-06-06
  • 如何正确的使用javascript
    本篇文章为大家展示了如何正确的使用javascript,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。使用javascript的方法:可以用script标签引入<script type...
    99+
    2023-06-14
  • 如何正确的使用springcloud
    这期内容当中小编将会给大家带来有关如何正确的使用springcloud,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、微服务简介 Ⅰ、我对微服务的理解微服务是软件开发的一种架构方式,由单一的应用小程序构...
    99+
    2023-06-14
  • 如何正确的使用ArrayList
    今天就跟大家聊聊有关如何正确的使用ArrayList,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。ArrayList简介ArrayList 是一个数组队列,相当于 动态数组。与Jav...
    99+
    2023-05-31
    arraylist
  • 如何正确使用@property
    本篇内容主要讲解“如何正确使用@property”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何正确使用@property”吧!他们是这样说的:class People: ...
    99+
    2023-06-15
  • 如何正确使用WideCharToMultiByte
    要正确使用WideCharToMultiByte函数,需要按照以下步骤操作:1. 确定要转换的宽字符编码方式。WideCharToM...
    99+
    2023-09-26
    使用
  • 如何正确使用MVCC
    这篇文章主要讲解了“如何正确使用MVCC”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何正确使用MVCC”吧! 简单理解版以下先引用我之前写过的...
    99+
    2024-04-02
  • 如何正确的使用Class类
    这篇文章给大家介绍如何正确的使用Class类,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。任何一个类都是Class类的实例对象,这个实例对象有三种表示方式第一种表示方式(任何一个类都有一个隐含的静态成员变量class)...
    99+
    2023-05-31
    class类
  • 如何正确的使用Docker Machine
    本篇文章给大家分享的是有关如何正确的使用Docker Machine,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Docker 是一个 Client-Server 架构的应用,...
    99+
    2023-06-06
  • 如何正确的使用puppeteer库
    如何正确的使用puppeteer库,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.初始化项目注: 这里我们会使用到 es6/7 的新特性...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作