Java的JSONPath(fastjson)使用总结

背景

最近使用json实现复杂业务配置, 因为功能需要解析读取json的中节点数据。如果使用循环或者stream处理,可以实现,但是都过于麻烦。在想能否使用更简单json读取方式,正好发现fastjson支持该功能,本文做一个记录

案例说明

示例1使用fastjson实现,依赖如下

xml 复制代码
           <!--alibaba.json和依赖包-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.79</version>
            </dependency>

为了对比写法便捷性,示例2也提供jackson的部分实现方式。

示例1. fastjson实现json指定节点按条件过滤提取数据

使用 JSONPath.eval 来筛选 JSON 数据中符合特定条件的元素。以下是使用 eval 方法提取 author 等于 "Nigel Rees" 的那条记录的示例代码:

java 复制代码
public class JSONPathExample {
    public static void main(String[] args) {
        String json = "{\n" +
                "  \"store\": {\n" +
                "    \"book\": [\n" +
                "      { \"category\": \"reference\", \"author\": \"Nigel Rees\", \"title\": \"Sayings of the Century\", \"price\": 8.95 },\n" +
                "      { \"category\": \"fiction\", \"author\": \"Evelyn Waugh\", \"title\": \"Sword of Honour\", \"price\": 12.99 },\n" +
                "      { \"category\": \"fiction\", \"author\": \"Herman Melville\", \"title\": \"Moby Dick\", \"price\": 8.99 },\n" +
                "      { \"category\": \"fiction\", \"author\": \"J. R. R. Tolkien\", \"title\": \"The Lord of the Rings\", \"price\": 22.99 }\n" +
                "    ],\n" +
                "    \"bicycle\": {\n" +
                "      \"color\": \"red\",\n" +
                "      \"price\": 19.95\n" +
                "    }\n" +
                "  }\n" +
                "}";

        JSONObject jsonObject = JSON.parseObject(json);
        JSONArray result = (JSONArray) JSONPath.eval(jsonObject, "$.store.book[?(@.author == 'Nigel Rees')]");

        for (Object book : result) {
            System.out.println(book);
        }
    }
}

运行结果如下,符合预期。而且代码非常简洁。

复制代码
{"author":"Nigel Rees","price":8.95,"category":"reference","title":"Sayings of the Century"}

示例2. jackson实现json指定节点按条件过滤提取数据

jackson 不支持直接使用 JSONPath 表达式,但可以通过结合 Jackson 和 Java 流操作实现类似的功能。以下是一个使用 Jackson 过滤 JSON 数据中 type 为 'AggregateRoot' 的节点的示例:

java 复制代码
public class JacksonExample {
    public static void main(String[] args) throws IOException {
        String json = "{\n" +
                "  \"classDiagram\": {\n" +
                "    \"nodes\": [\n" +
                "      { \"id\": \"1\", \"type\": \"AggregateRoot\", \"name\": \"Node1\" },\n" +
                "      { \"id\": \"2\", \"type\": \"Entity\", \"name\": \"Node2\" },\n" +
                "      { \"id\": \"3\", \"type\": \"AggregateRoot\", \"name\": \"Node3\" },\n" +
                "      { \"id\": \"4\", \"type\": \"ValueObject\", \"name\": \"Node4\" }\n" +
                "    ]\n" +
                "  }\n" +
                "}";

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(json);
        JsonNode nodesNode = rootNode.path("classDiagram").path("nodes");

        List<Map<String, Object>> nodes = new ArrayList<>();

        if (nodesNode.isArray()) {
            nodes = StreamSupport.stream(nodesNode.spliterator(), false)
                    .filter(node -> "AggregateRoot".equals(node.path("type").asText()))
                    .map(node -> objectMapper.convertValue(node, Map.class))
                    .collect(Collectors.toList());
        }

        for (Map<String, Object> node : nodes) {
            System.out.println(node);
        }
    }
}

总结

fastjson的JSONPath.eval方法对于快速解析json数据十分便利,后续再记录更多的使用技巧。

相关推荐
MetaLite3 分钟前
Spring 同一个类里调用 @CacheEvict,为什么缓存没清掉?
java·spring·缓存
sunburn-18 分钟前
数据库聚合查询完整教程:从基础函数到实战统计
java·数据库·mysql·数据库开发
wangchunyu11425 分钟前
JAVA 类加载机制与双亲委派模型
java·开发语言
小蒜学长39 分钟前
基于 Spring Boot 的英语单词背诵系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
lambo mercy1 小时前
持久化01——线程级持久化
java·开发语言·jvm
CoderYanger1 小时前
Java EE 进阶:5. Spring IoC&DI(第一弹):Spring IoC
java·开发语言·spring boot·spring·面试·职场和发展·java-ee
zyseo81 小时前
谷歌SEO 内容更新焕新流程:让老页面重新起量
java·前端·javascript
萧瑟余晖2 小时前
Spring Data JDBC与R2DBC详解
java·后端·spring
杰克尼2 小时前
今日面试题总结
java·开发语言·人工智能·langchain
估值探索者2 小时前
【Python量化组合管理实战 02】钱该怎么分?等权、波动率倒数与动态评分三种配权实测
java·开发语言·python·接口·股票数据api接口