断言
断言简单点说就是满足一定条件的逻辑表达式.在Springboot Cloud Gateway中匹配路由的断言及Java8中提供的Predicate接口都是断言.
JsonPath中有三种方式创建断言: 行内断言, 过滤器断言, 自定义断言
准备json数据
{
"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
}
},
"expensive": 10
}
Book实体
@Data
public static class Book {
/**
* 分类
*/
private String category;
/**
* 作者
*/
private String author;
/**
* 标题
*/
private String title;
/**
* 价格
*/
private Double price;
/**
* 书籍编号
*/
private String isbn;
}
maven坐标
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.9</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.7.0</version>
</dependency>
0,通过三种断言实现抽取book对象包含isbn属性同时price属性的值要大于10
1,行内断言
行内断言定义在计算路径中
TypeRef<List<Book>> typeRef = new TypeRef<List<Book>>(){};
// 行内断言
List<Book> books = JsonPath.parse(jsonData).read("$..book[?(@.isbn && @.price > 10)]", typeRef);
Console.log(JSONUtil.toJsonStr(books));
可以使用&& 和 ||组合多种断言,比如[?(@.price < 10 && @.category == 'fiction')]
, [?(@.category == 'reference' || @.price > 10)]
,[?(!(@.price < 10 && @.category == 'fiction'))]
.
2,过滤器断言
使用Filter API构建断言
- 方式1
// 过滤器断言 1
Filter filter = Filter.filter(Criteria.where("isbn").exists(true).and("price").gt(10));
List<Book> books = JsonPath.parse(jsonData).read("$..book[?]", filter);
Console.log(JSONUtil.toJsonStr(books));
- 方式2
// 过滤器断言 2
Filter filter = Filter.filter(Criteria.where("isbn").exists(true)).and(Criteria.where("price").gt(10));
List<Book> books = JsonPath.parse(jsonData).read("$..book[?]", filter);
Console.log(JSONUtil.toJsonStr(books));
- 方式3
// 过滤器断言 3
Filter filter1 = Filter.filter(Criteria.where("isbn").exists(true));
Filter filter2 = Filter.filter(Criteria.where("price").gt(10));
List<Book> books = JsonPath.parse(jsonData).read("$..book[?][?]", filter1,filter2);
Console.log(JSONUtil.toJsonStr(books));
注意路径中的过滤器占位符?, 其中占位符的数量要和过滤器的数量一致
3,自定义断言
// 自定义断言
Predicate booksWithISBNAndPrice = ctx -> ctx.item(Map.class).containsKey("isbn") && (Double)ctx.item(Map.class).get("price") > 10;
List<Book> books = JsonPath.read(document,"$..book[?]", booksWithISBNAndPrice);
Console.log(JSONUtil.toJsonStr(books));
总结:
- 以上3种方式的断言使用方法都可以相互转换
- 行内断言和过滤器断言使用方便灵活
- 自定义断言灵活但是不好理解和编写