Mastering JsonPath Validation: A Groovy-Powered Framework for Async Socket Testing

This article walks through the design and implementation of a custom JsonPath validation library using Groovy operator overloading, detailing the core enums, verification bean, arithmetic handling, and practical demo code, while providing repository links for Gitee and GitHub.

FunTester
FunTester
FunTester
Mastering JsonPath Validation: A Groovy-Powered Framework for Async Socket Testing

Overview

Utility library combines JsonPath parsing with Groovy operator overloading to enable flexible validation of JSON responses, especially for asynchronous socket interfaces.

Supported Operations

Comparison operators: > (greater), < (less), = (equal), ~ (regex).

Arithmetic operators applied before comparison: + (add), - (subtract), * (multiply), / (divide).

JsonVerify Implementation

/**
 * Determine if the string matches the expectation
 */
public boolean fit(String str) {
    logger.info("verify对象: {},匹配的字符串: {}", extra, str);
    OPS o = OPS.getInstance(str.charAt(0));
    def res = str.substring(1);
    switch (o) {
        case OPS.GREATER:
            return this > res;
        case OPS.LESS:
            return this < res;
        case OPS.EQUAL:
            return this == res;
        case OPS.REGEX:
            return this ==~ res;
        default:
            ParamException.fail("参数错误!");
    }
}

/**
 * Determine if the result matches the expectation after an arithmetic operation
 */
public boolean fitFun(String str) {
    def split = str.split(REG_PART, 2);
    def handle = split[0];
    def ops = split[1];
    HPS h = HPS.getInstance(handle.charAt(0));
    def hr = handle.substring(1);
    switch (h) {
        case HPS.PLUS:
            def n = getInstance((this + hr) as String);
            return n.fit(ops);
        case HPS.MINUS:
            def n = getInstance((this - hr) as String);
            return n.fit(ops);
        case HPS.MUL:
            def n = getInstance((this * hr) as String);
            return n.fit(ops);
        case HPS.DIV:
            def n = getInstance((this / hr) as String);
            return n.fit(ops);
        default:
            ParamException.fail("参数错误!");
    }
}

static enum OPS {
    GREATER, LESS, EQUAL, REGEX;
    static OPS getInstance(char c) {
        switch (c) {
            case '>': return GREATER;
            case '<': return LESS;
            case '=': return EQUAL;
            case '~': return REGEX;
            default: ParamException.fail("判断操作符参数错误!");
        }
    }
}

static enum HPS {
    PLUS, MINUS, MUL, DIV;
    static HPS getInstance(char c) {
        switch (c) {
            case '+': return PLUS;
            case '-': return MINUS;
            case '*': return MUL;
            case '/': return DIV;
            default: ParamException.fail("运算操作符参数错误!");
        }
    }
}

VerifyBean Verification Object

package com.fun.base.bean;

import com.alibaba.fastjson.JSON;
import com.fun.base.exception.ParamException;
import com.fun.config.VerifyType;
import com.fun.utils.JsonUtil;
import com.fun.utils.Regex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.fun.config.Constant.REG_PART;

class VerifyBean extends AbstractBean implements Serializable, Cloneable {
    private static Logger logger = LoggerFactory.getLogger(VerifyBean.class);
    private static final long serialVersionUID = -1595942567071153982L;

    VerifyType type;
    String verify; // verification expression
    String value;  // content to verify
    String des;    // description
    boolean isVerify;
    boolean result;

    VerifyBean(String verify, String value, String des) {
        this.value = value;
        this.des = des;
        String[] split = verify.split(REG_PART, 2);
        this.verify = split[1];
        this.type = VerifyType.getRequestType(split[0]);
    }

    boolean verify() {
        isVerify = true;
        try {
            switch (type) {
                case CONTAIN:
                    result = value.contains(verify);
                    break;
                case REGEX:
                    result = Regex.isRegex(value, verify);
                    break;
                case JSONPATH:
                    String[] sp = verify.split(REG_PART, 2);
                    String path = sp[0];
                    String v = sp[1];
                    JsonUtil instance = JsonUtil.getInstance(JSON.parseObject(value));
                    result = instance.getVerify(path).fit(v);
                    break;
                case HANDLE:
                    String[] hp = verify.split(REG_PART, 2);
                    String hPath = hp[0];
                    String hExp = hp[1];
                    JsonUtil hInst = JsonUtil.getInstance(JSON.parseObject(value));
                    result = hInst.getVerify(hPath).fitFun(hExp);
                    break;
                default:
                    ParamException.fail("验证类型参数错误!");
            }
        } catch (Exception e) {
            logger.warn("验证出现问题!", e);
            result = false;
        } finally {
            logger.info("verify对象 {} ,验证结果: {}", verify, result);
        }
        return result;
    }

    @Override
    public VerifyBean clone() throws CloneNotSupportedException {
        return new VerifyBean(this.verify, this.value, this.des);
    }
}

Demo Usage

public static void main(String[] args) {
    String json = "{\"msg\":\"\",\"code\":1,\"data\":{\"role\":\"T\",\"s_sid\":123,\"deviceVersion\":\"1.0\",\"userId\":61951375269,\"token\":\"c5d28b3e919d45e0a06af2e4d346698a\"},\"cmd\":\"registerResponse\"}";
    VerifyBean bean1 = new VerifyBean("contain|61951375269", json, "Demo");
    VerifyBean bean2 = new VerifyBean("regex|.*data.*", json, "Demo");
    VerifyBean bean3 = new VerifyBean("jsonpath|$.data.s_sid|=123", json, "Demo");
    VerifyBean bean4 = new VerifyBean("jsonpath|$.data.s_sid|>100", json, "Demo");
    VerifyBean bean5 = new VerifyBean("jsonpath|$.cmd|~.*Response.*", json, "Demo");
    VerifyBean bean6 = new VerifyBean("handle|$.code|*200|=200.0", json, "Demo");
    System.out.println(bean1.verify());
    System.out.println(bean2.verify());
    System.out.println(bean3.verify());
    System.out.println(bean4.verify());
    System.out.println(bean5.verify());
    System.out.println(bean6.verify());
}

Sample Console Output

true
true
true
true
true
true

Repository Links

Gitee: https://gitee.com/fanapi/tester

GitHub: https://github.com/JunManYuanLong/FunTester

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaAutomationtestingvalidationJsonPathGroovy
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.