断言简单点说就是满足一定条件的逻辑表达式.在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坐标
0,通过三种断言实现抽取book对象包含isbn属性同时price属性的值要大于10 1,行内断言org.projectlombok lombok 1.18.16 cn.hutool hutool-all 5.3.9 com.jayway.jsonpath json-path 2.7.0
行内断言定义在计算路径中
TypeRef> typeRef = new TypeRef
>(){}; // 行内断言 List
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 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 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 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 books = JsonPath.read(document,"$..book[?]", booksWithISBNAndPrice);
Console.log(JSONUtil.toJsonStr(books));
总结:
- 以上3种方式的断言使用方法都可以相互转换
- 行内断言和过滤器断言使用方便灵活
- 自定义断言灵活但是不好理解和编写



