大数据

json数据以表达式筛选过滤

需要使用包:json-path

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

示例代码:

import com.jayway.jsonpath.JsonPath;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        String cdcJson = "{\n" +
                "  \"table\": \"linkman_information\",\n" +
                "  \"op\": \"u\",\n" +
                "  \"before\": {\n" +
                "    \"id\": 1001,\n" +
                "    \"linkman_id\": \"L001\",\n" +
                "    \"contact_info\": \"old@a.com\",\n" +
                "    \"delete_flag\": \"0\"\n" +
                "  },\n" +
                "  \"after\": {\n" +
                "    \"id\": 1001,\n" +
                "    \"linkman_id\": \"L002\",\n" +
                "    \"contact_info\": \"new@a.com\",\n" +
                "    \"delete_flag\": \"0\"\n" +
                "  }\n" +
                "}";

        // 提取 after 中的 contact_info
        String afterContact = JsonPath.read(cdcJson, "$.after.contact_info");
        System.out.println("After contact: " + afterContact); // → new@a.com

        // 提取 before 中的 delete_flag
        String beforeFlag = JsonPath.read(cdcJson, "$.before.delete_flag");
        System.out.println("Before flag: " + beforeFlag); // → 0

        // 构造谓词表达式
        String condition = "@.after.delete_flag == '0'";
        String jsonPath = "$[?(" + condition + ")]";

        // 执行查询
        List<?> result = JsonPath.read(cdcJson, jsonPath);
        if (!result.isEmpty()) {
            System.out.println("✅ 条件满足:delete_flag 为 '0'");
        } else {
            System.out.println("❌ 条件不满足");
        }

        // 判断 contact_info 是否变更 且 当前有效
        condition = "@.before.contact_info != @.after.contact_info && @.after.delete_flag == '0'";
        jsonPath = "$[?(" + condition + ")]";

        result = JsonPath.read(cdcJson, jsonPath);
        System.out.println("联系方式变更且有效?" + (!result.isEmpty())); // → true

        // 安全判断:contact_info 从 null 变为非空
        condition = "@.before.contact_info == null && @.after.contact_info != null";
        jsonPath = "$[?(" + condition + ")]";
        // 如果字段不存在,JsonPath 会抛 PathNotFoundException
        // 建议用 try-catch 或工具方法封装
        try {
            result = JsonPath.read(cdcJson, jsonPath);
            System.out.println("从空变为非空?" + (!result.isEmpty()));
        } catch (Exception e) {
            System.out.println("字段不存在,视为不匹配");
        }

        // 提取多个字段的变更值
        String contactBefore = JsonPath.read(cdcJson, "$.before.contact_info");
        String contactAfter = JsonPath.read(cdcJson, "$.after.contact_info");
        String linkmanBefore = JsonPath.read(cdcJson, "$.before.linkman_id");
        String linkmanAfter = JsonPath.read(cdcJson, "$.after.linkman_id");

        System.out.println("Contact changed: " + contactBefore + "" + contactAfter);
        System.out.println("Linkman changed: " + linkmanBefore + "" + linkmanAfter);
    }
}

SafeJsonPath.java

package com.learn;

import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;

import java.util.List;

public class SafeJsonPath {
    /**
     * 安全读取 JsonPath,避免 PathNotFoundException
     */
    public static Object readSafe(String json, String path) {
        try {
            return JsonPath.read(json, path);
        } catch (PathNotFoundException e) {
            return null;
        }
    }

    /**
     * 判断条件是否满足
     */
    public static boolean matches(String json, String conditionExpr) {
        if (conditionExpr == null || conditionExpr.trim().isEmpty()) {
            return true;
        }
        try {
            List<?> result = JsonPath.read(json, "$[?(" + conditionExpr + ")]");
            return result != null && !result.isEmpty();
        } catch (Exception e) {
            return false; // 表达式错误视为不匹配
        }
    }
}