测试开发【Mock平台】13基础:拦截器服务实现(四) 简单规则匹配逻辑

【Mock平台】为系列测试开发教程,从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台,希望作为一个实战项目对各位的测试开发学习之路有帮助,关注公众号发送“mock”获取github项目源码地址,大奇一个专注测试技术干货原创与分享的家伙。

接上一篇最外层接口的匹配,我们继续深入开发内层规则的匹配。其中规则的匹配会涉及到较多的判断处理,以及重复重复内容,所以我们先创建个匹配工具类,来进行代码类化开发。

public class QMockRuleUtil {
    // 规则匹配工具类
}

GET参数处理

实战项目为了简化处理,不论是GET参数还是POST BODY,不使用自带如之前讲到的getParameterMap方法,而是自定义一个方法,专门处理URL中请求参数"a=a1&b=b1&c=c1"成为JSON。如下代码处理进行一次&拆分,再进行一次=拆分。在这里值得注意的是对应值可能没有或者有多个等号的,我做了一定的兼容,但在实际应用过程中还可能出现其他特殊值的兼容情况,请想想如果遇到要如何处理?

public static JSONObject getJsonObjcetByQueryUrl(String paramStr){
        //String paramStr = "a=a1&b=b1&c=c1";
        String[] params = paramStr.split("&");
        JSONObject obj = new JSONObject();
        for (int i = 0; i < params.length; i++) {
            String[] param = params[i].split("=");
            if (param.length >= 2) {
                String key = param[0];
                String value = param[1];
                for (int j = 2; j < param.length; j++) {
                    value += "=" + param[j];
                }
                try {
                    obj.put(key,value);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }

QMockInterceptor.java类中preHandle在匹配接口后,如果是GET请求,我们对其URL参数后的串获取并用自定义的处理工具类方法转换成统一的JSON数据。

if ("GET".equals(requestMethod.toUpperCase())){
    try {

        if (request.getParameterMap().size()!=0) {
            // 获取GET请求参数
            String paramsStr = URLDecoder.decode(request.getQueryString(),"utf-8");
            // 通过自定义转换方法转换成通用的json数据
            reqParamsOrBody = QMockRuleUtil.getJsonObjcetByQueryUrl(paramsStr);
        }
        // resResult = QMockRuleUtil.matchFilter(mockApiEntity,mockApiRuleEntities,reqParamsOrBody);
    }
    catch (JSONException e){
        log.error(e.toString());
    }
}

这样先完成了GET参数的处理,注意这里有一行注释,将在最后一个核心公共方法实现后打开。

POST参数处理

GET的请求参数处理相对简单些,而对于POST一般对应的Body参数,当然也会可以同传Params参数。之前就讲过本套案例不做太复杂逻辑处理,如果有需要请在本系完成对应实战操作后,掌握了对应的技术能力后,根据项目需求进行扩展开发,如果真是对于Mock需求过滤有复杂的要求,一般就需要在产品需求交互上定义清楚,然后代码层面分层处理。

// 获取POST方法的中的Body数据
public static String getBodyString(HttpServletRequest request) throws IOException {
    StringBuilder sb = new StringBuilder();
    InputStream inputStream = null;
    BufferedReader reader = null;
    try {
        inputStream = request.getInputStream();
        reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
        String line = "";
        // 逐行读取
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // 返回JSON字符串
    return sb.toString();
}

getBodyString 工具类方法字符流的处理方法是在一个POST请求的BODY本身就是要求JSON格式的前提下实现的逻辑。在得到这个JSON字符串后直接进行类型转换即可。其他非JSON格式请求很少见,如果需要请进行通过header传类型做响应匹配处理。

else if ("POST".equals(requestMethod.toUpperCase())){
    try {
        String strbody = QMockRuleUtil.getBodyString(request);
        if (!strbody.isEmpty()) {
            reqParamsOrBody = JSON.parseObject(strbody);
        }

        // resResult = QMockRuleUtil.matchFilter(mockApiEntity,mockApiRuleEntities,reqParamsOrBody);
    }
        catch (JSONException e){
        log.error(e.toString());
    }
} 

在最后我们进行获取规则,增加最后else处理,便可完成完整的逻辑匹配接口和规则的逻辑。

if(mockApiEntities.size() == 1) {
    // 取得 Mock api 唯一值
    QMockApiEntity mockApiEntity = mockApiEntities.get(0);

    // 根据 api id 查询规则列表
    List<QMockApiRuleEntity> mockApiRuleEntities = qMockService.selectApiRuleList(mockApiEntity.getId());
    log.info("Mock规则个数:" + mockApiRuleEntities.size());

    // 根据不同的方法做不同的处理,目前只支持常用的GET和POST
    if ("GET".equals(requestMethod.toUpperCase())){
        // GET参数处理部分
        resResult = QMockRuleUtil.matchFilter(mockApiEntity,mockApiRuleEntities,reqParamsOrBody);
    } else if ("POST".equals(requestMethod.toUpperCase())){
       // POST参数处理部分省略
       resResult = QMockRuleUtil.matchFilter(mockApiEntity,mockApiRuleEntities,reqParamsOrBody);
    } else {
        resResult.put("code", 4008);
        resResult.put("msg", "Mock暂未支持的请求方法");
    }

} else if (mockApiEntities.size() > 1) {
    resResult.put("code", 5000);
    resResult.put("data", new JSONObject());
    resResult.put("msg", "MOCK匹配多个URI请检查配置");
}
else {
    resResult.put("code", 5000);
    resResult.put("data", new JSONObject());
    resResult.put("msg", "MOCK未匹配任何URI请先添加把");
}

上述代码中有“根据 api id 查询规则列表” 的查询,这个查库实现参考上一篇和最初几篇套路式自己我先实现,也当做是检验下自我脱稿编程的代码能力的检验了。学习是需要自我实战才能有效果的,多花点时间将学过的东西独立实践,而不是照着练一遍,你将收获更大的进步。当然如果不会也不用担心,我将在下篇给出代码详细。

简单规则匹配

通过上述的GET/POST的参数获取转换最终得到一个reqParamsOrBody,然后还有上一篇中的得到mockApiEntitymockApiEntity 三个对象数据,这样我们就可以对其简单的匹配逻辑处理了,关键的解释放在代码注释里了。

 // Mock Rule 匹配逻辑
public static JSONObject matchFilter(QMockApiEntity mockApiEntity, List<QMockApiRuleEntity> mockApiRuleEntities, JSONObject reqParamsOrBody){

    JSONObject resResult = new JSONObject();

    // 循环规则列表
    for(QMockApiRuleEntity ruleEntity:mockApiRuleEntities){
        // 如果规则没有配置个过滤条件跳过
        if((ruleEntity.getReqFilter().isEmpty() || ruleEntity.getReqFilter() == null ) && reqParamsOrBody == null) {
            resResult = ruleEntity.getResBody();
            break;
        }

        // 如果有请求参数和配置条件都有进行匹配
        if(!ruleEntity.getReqFilter().isEmpty() && reqParamsOrBody != null) {

            // 规则大于请求参数认为不合理,不做此规则判定
            if (ruleEntity.getReqFilter().size() > reqParamsOrBody.size()){
                continue;
            }

            // 非合理条件均不存在进行key value的一一判定,这里同样简化只做一级过滤
            JSONArray filters = ruleEntity.getReqFilter();
            Boolean assertResult = false;
            for(int i=0; i< filters.size(); i++) {
                // 先看是否有匹配key+相等value 
                // 在页面添加规则的时候录入数据的固定格式为 [{"key":"job","value":"test"}]
                String key = filters.getJSONObject(i).getString("key");
                if(reqParamsOrBody.containsKey(key) && reqParamsOrBody.get(key).toString().equals(filters.getJSONObject(i).get("value"))) {
                    assertResult = true;
                } else {
                    assertResult = false;
                }
            }
            // 如果有获取规则返回值
            if( assertResult ) {
                resResult = ruleEntity.getResBody();
                break;
            }
        }
    }
    // 全没有返回默认
    if (resResult.isEmpty()) {
        resResult = mockApiEntity.getResDefault();
    }

    return resResult;
}

我们最终做下联调运行测试:

特别提醒1:不要忘记需要先自己实现“qMockService.selectApiRuleList”,这是运行前提

​特别提醒2:以上代码文章里不是一下写出来的,实际的边那中中是要不断debug出来的。也非常不建议不是一痛写或者拷贝复制后就直接运行,然后报错太多又很抓狂。

  • GET接口规则命中
    get

  • POST接口规则命中
    post

至此,本篇教程实现到这里,在上一篇基础上我们进一步实现了接口规则的匹配。有了这个能力支持,我们就可以针对同一个接口不同数值的请求匹配返回对应的值了。

下一篇我们会给出接口规则的请求表和全过程,下下篇是一个扩展知识点,然后我们回归到页面的交互开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/396123.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RocketMQ—RocketMQ消息重复消费问题

RocketMQ—RocketMQ消息重复消费问题 重复消费问题的描述 什么情况下会发生重复消费的问题&#xff1a; 生产者多次投递消息&#xff1a;如果生产者发送消息时&#xff0c;连接有延迟&#xff0c;MQ还没收到消息&#xff0c;生产者又发送了一次消息&#xff1b; 消费者方扩容…

【漏洞复现-通达OA】通达OA WHERE_STR 存在前台SQL注入漏洞

一、漏洞简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台。通达OA WHERE_STR存在前台SQL注入漏洞,攻击者可通过该漏洞获取数据库敏感信息。 二、影响版本 ●…

将其它输入法的词库转换为微软拼音输入法的自学习词库

上班第一天&#xff0c;我删除了搜狗输入法 曾几何时&#xff0c;搜狗拼音输入法&#xff0c;以丰富的词库&#xff0c;实用的设置成为我电脑端主要的中文输入法。但新年上班的第一天&#xff0c;我彻底删除了它&#xff0c;回归到微软拼音输入法。因为&#xff0c;最近&#…

同学在外包干了两年的点点点,24岁人就快废了

前言 简单的说下&#xff0c;我大学的一个同学&#xff0c;毕业后我自己去了自研的公司&#xff0c;他去了外包&#xff0c;快两年了我薪资、技术各个方面都有了很大的提升&#xff0c;他在外包干的这两年人都要废了&#xff0c;技术没一点提升&#xff0c;学不到任何东西&…

辽宁博学优晨教育科技有限公司视频剪辑培训靠谱吗?

在数字媒体日益繁荣的今天&#xff0c;视频剪辑已成为一项炙手可热的技能。不少培训机构纷纷涉足这一领域&#xff0c;辽宁博学优晨教育科技有限公司便是其中之一。然而&#xff0c;面对众多的选择&#xff0c;很多人不禁要问&#xff1a;辽宁博学优晨教育科技有限公司的视频剪…

中国传媒网CEO徐晓艺:媒体融合发展业态新媒体年后在沪召开

近日,在“坚守媒体初心,拥抱AI时代”2023外滩新媒体年会上,有多项合作达成。 在当前竞争激烈的市场环境中,媒体宣传已经成为企业品牌推广不可或缺的一环。对于很多企业来说往往会犯一个错误,就是默默地参加了展会,并没有进行媒体营销。展会是一种非常有力的宣传和推广方式,可以…

网络安全综合实验

1.实验拓扑 在这里注意因为第四个要求配置双击热备&#xff0c;我们可以第一时间配置&#xff0c;避免二次重复配置消耗时间 4、FW1和FW3组成主备模式的双机热备 具体配置位置在系统-->高可靠性-->双机热备-->配置 这里上行链路有两组&#xff0c;分别为电信和移动&…

RK356x U-Boot研究所(驱动篇)4.2.2 DRM代码结构分析

谈到 drm 就涉及到 libdrm 库,它是一个跨驱动的中间件,它允许用户空间应用(例如作为Mesa和2D驱动程序)通过DRI与内核通信协议。 如下DRM结构图: libdrm 是DRM下沟通驱动和用户层的库。过去APP可能是使用open(framebuff)这样的方式来和图形驱动沟通,但是在现在的硬件演化…

【项目管理】CMMI-项目监督和控制

项目监督和控制&#xff08;Monitoring and Control, MC&#xff09;的目的是通过周期性地跟踪项目计划的各种性能参数如工作产品的规模、工作量、成本、进度、风险等&#xff0c;不断地了解项目的进展情况&#xff0c;以便当项目实际进展状况显著偏离项目计划时能够及时采取纠…

【Flink入门修炼】1-4 Flink 核心概念与架构

前面几篇文章带大家了解了 Flink 是什么、能做什么&#xff0c;本篇将带大家了解 Flink 究竟是如何完成这些的&#xff0c;Flink 本身架构是什么样的&#xff0c;让大家先对 Flink 有整体认知&#xff0c;便于后期理解。 一、Flink 组件栈 Flink是一个分层架构的系统&#xf…

Shiro-05-5 分钟入门 shiro 安全框架实战笔记

序言 大家好&#xff0c;我是老马。 前面我们学习了 web 安全之 Spring Security 入门教程 这次我们来一起学习下另一款 java 安全框架 shiro。 什么是Apache Shiro&#xff1f; Apache Shiro是一个功能强大且易于使用的Java安全框架&#xff0c;它为开发人员提供了一种直…

压缩感知——革新数据采集的科学魔法

引言&#xff1a; 在数字时代&#xff0c;数据以及数据的收集和处理无处不在。压缩感知(Compressed Sensing, CS)是一种新兴的数学框架&#xff0c;它挑战了我们传统上对数据采集和压缩的看法&#xff0c;给医学图像、天文观测、环境监测等领域带来了颠覆性的影响。但到底什么…

模板(函数模板)---C++

模板目录 模板1.模板概念&#xff12;.泛型编程 1.函数模板1.1 函数模板语法1.2 函数模板注意事项1.3 普通函数与函数模板的区别1.4 普通函数与函数模板的调用规则1.5 模板的局限性1.6 函数模板案例 模板 1.模板概念 模板就是建立通用的模具&#xff0c;大大提高复用性。 模板…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-静态内存

目录 一、内存管理二、静态内存2.1、静态内存运行机制2.2、静态内存开发流程2.3、静态内存接口2.4、实例2.5、代码分析&#xff08;待续...&#xff09;坚持就有收货 一、内存管理 内存管理模块管理系统的内存资源&#xff0c;它是操作系统的核心模块之一&#xff0c;主要包括…

百度地图接口 | 实现校验收货地址是否超出配送范围

目录 1. 环境准备 2. 代码开发 2.1 application.yml 2.2 OrderServiceImpl &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步涉猎Py…

Linux 动静态库

目录 库的概念 动静态库的制作 动态链接与静态链接 库的使用 库的概念 程序库&#xff08;Library&#xff09;&#xff0c;一般简称为“库”&#xff0c;是一组预先编写好的可重用代码的集合。这些代码可以包括函数、类、变量、常量、数据结构、宏等&#xff0c;它们通常…

可转债和股票有哪些区别?可转债和股票哪个好?

可转债&#xff0c;全称可转换债券&#xff0c;指的是持有者可以在特定时期、按特定条件&#xff0c;将其转换为特定数量的另一种证券的债券。这种债券可以转换成公司的普通股票。 如果债券持有人看好发债公司股票增值潜力&#xff0c;在宽限期之后可以行使转换权&#xff0c;…

键盘输入4个数,从小到大排序

题目 键盘输入4个整数&#xff0c;从小到大排序 思路 代码 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//键盘输入4个整数&#xff0c;从小到大排序 int main() {int n1, n2, n3, n4;scanf_s("%d %d %d %d", &n1, &n2, &n3, &n4);…

springboot网上宠物领养管理系统-计算机毕业设计源码05971

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;宠物行业当然也不例外。网上宠物领养管理系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff…
最新文章