JSON对象标记语法验证类

2021-01-05 09:59:44 浏览数 (1)

在接触过JsonPath工具,我发现了使用标记语法编写文本形式的验证的可行性。在完成了基本JsonPath功能封装和Groovy终极重载操作符功能之后,自我感觉已经非常完善了,所以停了一阵子。之前的成果如下:

JsonPath文章合集

  • JsonPath实践(一)
  • JsonPath实践(二)
  • JsonPath实践(三)
  • JsonPath实践(四)
  • JsonPath实践(五)
  • JsonPath实践(六)
  • JsonPath工具类封装
  • JsonPath工具类单元测试
  • JsonPath验证类既Groovy重载操作符实践

在最近实践的一个Socket接口异步验证的功能时,对于响应结果又有了新的验证需求。目前我的方案是单独写一个「VerifyBean」对象,用来完成不同验证需求的实现。每一个对象都是存储一种验证方式,然后存储验证结果。

对实际值进行运算

这个功能为了方便获取到实际值以后,进行「加」「减」「乘」「除」运算以后再与期望值进行比较。比如用户消费场景,例如随机立减(吐槽一下立减一分钱),用「余额 商品金额>原余额」方程可以验证数据的准确性。

JsonVerify功能具体实现如下:

代码语言:javascript复制

    /**
     * 判断是否符合期望
     * @param str
     * @return
     */
    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("参数错误!")
        }
    }

    /**
     * 判断是否符合操作后期望
     * @param str
     * @return
     */
    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("运算操作符参数错误!")
            }
        }
    }

重载操作符的代码可以通过JsonPath验证类既Groovy重载操作符实践文章查看,或者访问我的仓库:

  • Gitee地址https://gitee.com/fanapi/tester
  • GitHub地址https://github.com/JunManYuanLong/FunTester

VerifyBean验证对象

这个比较简单,目前来讲满足需求。

代码语言:javascript复制
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 com.fun.utils.Time
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import java.util.concurrent.atomic.AtomicLong

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
    /**
     * 待验证内容
     */
    String value

    String des

    boolean isVerify

    boolean result;

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

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

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

Demo演示

测试代码:

代码语言:javascript复制
    public static void main(String[] args) {
        String a = "{"msg":"","code":1,"data":{"role":"T","s_sid":123,"deviceVersion":"1.0","userId":61951375269,"token":"c5d28b3e919d45e0a06af2e4d346698a"},"cmd":"registerResponse"}"
        def bean1 = new VerifyBean("contain|61951375269", a, "FunTester")
        def bean2 = new VerifyBean("regex|.*data.*", a, "FunTester")
        def bean3 = new VerifyBean("jsonpath|$.data.s_sid|=123", a, "FunTester")
        def bean4 = new VerifyBean("jsonpath|$.data.s_sid|>100", a, "FunTester")
        def bean5 = new VerifyBean("jsonpath|$.cmd|~.*Response.*", a, "FunTester")
        def bean6 = new VerifyBean("handle|$.code|*200|=200.0", a, "FunTester")
        println bean1.verify()
        println bean2.verify()
        println bean3.verify()
        println bean4.verify()
        println bean5.verify()
        println bean6.verify()

    }

控制台输出:

代码语言:javascript复制
INFO-> 当前用户:fv,IP:10.60.192.21,工作目录:/Users/fv/Documents/workspace/fun/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> 验证校验方式方式:contain
INFO-> 验证校验方式方式:regex
INFO-> 验证校验方式方式:jsonpath
INFO-> 验证校验方式方式:jsonpath
INFO-> 验证校验方式方式:jsonpath
INFO-> 验证校验方式方式:handle
INFO-> verify对象 61951375269 ,验证结果: true
true
INFO-> verify对象 .*data.* ,验证结果: true
true
INFO-> verify对象: 123,匹配的字符串: =123
INFO-> verify对象 $.data.s_sid|=123 ,验证结果: true
true
INFO-> verify对象: 123,匹配的字符串: >100
INFO-> verify对象 $.data.s_sid|>100 ,验证结果: true
true
INFO-> verify对象: registerResponse,匹配的字符串: ~.*Response.*
INFO-> verify对象 $.cmd|~.*Response.* ,验证结果: true
true
INFO-> verify对象: 200.0,匹配的字符串: =200.0
INFO-> verify对象 $.code|*200|=200.0 ,验证结果: true
true

Process finished with exit code 0


  • FunTester,简直完美实现了我的需求,下一步开始对Socket接口编写异步验证线程,敬请期待!

「FunTester」,非著名测试开发,文章记录学习和感悟,欢迎关注,交流成长。

0 人点赞