springboot vue测试平台接口定义及发送请求功能实现
作者:把苹果咬哭的测试笔记
基于 springboot+vue 的测试平台开发
继续更新
添加的接口,我要来调试确定是否是通的,那么要发送接口请求,今天来实现这个功能,先预览一下:
捋一下思路,分为三步走:
点击发送按钮,调用后端接口后端接口处理内部,发送http接口请求后端接口把响应返回给前端展示
一、http客户端选型
为了更方便快捷的开发功能,直接选用 hutool 框架中封装好的 http客户端。
官方介绍:Hutool-http 针对JDK 的HttpUrlConnection做一层封装,简化了HTTPS请求、文件上传、Cookie记忆等操作,使Http请求变得无比简单。
Hutool-http的核心集中在两个类:
HttpRequest
HttpResponse
同时针对大部分情境,封装了HttpUtil工具类。根据Hutool的“便捷性与灵活性并存”原则,HttpUtil 的存在体现了便捷性,那 HttpRequest对象的使用则体现了灵活性,使用此对象可以自定义更多的属性给请求,以适应Http请求中的不同场景(例如自定义header、自定义cookie、自定义代理等等)。
看过介绍,我浏览了下源代码,然后测试了一下,发现可以满足我使用需求。
// get1 @Test void get1() { String result1 = HttpUtil.get("http://localhost:8080/bloomtest/user/useInfo?token=admin-token"); System.out.println(result1); } // get2 @Test void get2() { Map<String, Object> paramMap = new HashMap<>(); paramMap.put("id", 33); String result2 = HttpRequest.get("http://localhost:8080/bloomtest/apiDefinition/getApi") .form(paramMap) .execute() .body(); System.out.println(result2); }
比如,发送get请求,HttpUtil 其实是基于 HttpRequest 的进一步分装,我这里还是直接统一使用 HttpRequest 。
另外,发送 post 请求也很简单,可以直接传入 json 字符串:
@Test void testPost() { String reqBody = "{\n" + " \"projectName\": \"项目zzz1\",\n" + " \"description\": \"测试新增项目\"\n" + "}"; //链式构建请求 String result3 = HttpRequest.post("http://localhost:8080/bloomtest/project/add") // .header(Header.CONTENT_TYPE, "application/json")//头信息,多个头信息多次调用此方法即可 // .timeout(20000)//超时,毫秒 .body(reqBody) .execute().body(); }
关于http请求的常用信息,请求头、参数、delete/put 等等其他方法,框架都是支持的,目前我只实现最基本的需求。
二、后端接口实现
测试过了上面的代码,心里就有数了,在后端接口里就看怎么使用它了。
这个发送请求的接口,目前需要支持如下:
get、post 方法查询参数(/list?id=3)、rest参数(/list/3)以及请求 body(json)
header暂时先不加,目前我项目里的接口都不需要传指定的 header,后期实现了权限之后再对应完善代码。
1. controller 层
ApiDefinitionController 类中继续新增处理器方法。
@PostMapping("/apiTestRun") public Result apiTestRun(@RequestBody ApiRunTestRequest apiRunTestRequest) { return Result.success(apiDefinitionService.apiTestRun(apiRunTestRequest)); }
2. service 层
对应service层实现,先放出全部代码,目前还是以初期实现为主,代码后续可能会进一步优化:
public JSONObject apiTestRun(ApiRunTestRequest request) { // url 拼接 String url = request.getHost() + request.getPath(); // 判断不同请求参数类型:0 query参数,1 rest参数, 2使用 body参数 int queryType = request.getRequestType(); if (queryType == 0) { // query 参数 HashMap<String, Object> paramMap = new HashMap<>(); JSONArray jsonArray = JSONArray.parseArray(request.getRequest()); for (int i=0; i<jsonArray.size(); i++) { paramMap.put(jsonArray.getJSONObject(i).get("queryKey").toString(), jsonArray.getJSONObject(i).get("value")); } if (request.getMethod().equals("get")) { String result = HttpRequest.get(url) .form(paramMap) .execute() .body(); return JSONObject.parseObject(result); } if (request.getMethod().equals("post")) { String result = HttpRequest.post(url) .form(paramMap) .execute() .body(); return JSONObject.parseObject(result); } } else if (queryType == 1) { // rest参数 HashMap<String, Object> paramMap = new HashMap<>(); JSONArray jsonArray = JSONArray.parseArray(request.getRequest()); for (int i=0; i<jsonArray.size(); i++) { paramMap.put(jsonArray.getJSONObject(i).get("restKey").toString(), jsonArray.getJSONObject(i).get("value")); } // 去掉path后面的参数,还原path List<String> list = Arrays.asList(request.getPath().split("/\\{")); String orginPath = list.get(0); // 解析path中的参数,确认参数拼接顺序 List<String> resultFindAll = ReUtil.findAll("(?<=\\{)(.+?)(?=\\})", request.getPath(), 0); String appendParamPath = ""; for (String i : resultFindAll) { appendParamPath = appendParamPath.concat("/" + paramMap.get(i)); } // 发送请求 if (request.getMethod().equals("get")) { String result = HttpRequest .get(request.getHost() + orginPath + appendParamPath) .execute() .body(); return JSONObject.parseObject(result); } if (request.getMethod().equals("post")) { String result = HttpRequest .post(request.getHost() + orginPath + appendParamPath) .execute() .body(); return JSONObject.parseObject(result); } } else if (queryType == 2) { // 请求体 if (request.getMethod().equals("post")) { String reqBody = request.getRequest(); String result = HttpRequest.post(url) .body(reqBody) .execute().body(); return JSONObject.parseObject(result); } // 请求体 if (request.getMethod().equals("get")) { String reqBody = request.getRequest(); String result = HttpRequest.get(url) .body(reqBody) .execute().body(); return JSONObject.parseObject(result); } } return null; }
乍一看比较多,其实分开看就好:
- 根据参数类型,分别对于 query、rest、body 的请求参数情况进行处理
- 在其中每种类型里,又区分了 get、post 方法
简单介绍下其中各种的要点。
(1)query 参数
主要是前面的 2 步:
拿到前端的入参,解析成 JSONArray,内部元素类型又是 JSONObject
遍历 JSONArray,通过jsonArray.getJSONObject(i)方法获取各 JSONObject 的 key,对应前端入参的queryKey和value,就是参数名和参数值。
接着发送请求,拿到的返回是一个 String,解析成 JSONObject 返回给 controller
(2)rest 参数
处理 rest 参数稍微麻烦了些,比如:localhost:8080/bloomtest/module/list/3
,最后的3
才是参数。
处理过程就像我注视写的:
获取前端传来的参数
首先跟上面一样,获取到前端的参数名和值,放到 HashMap 里,熟悉 python的童鞋就当作放到字典里了。
解析path中的参数,确认参数拼接顺序
因为参数名需要跟 url 里的拼接的值顺序对应上才行,接口里保存的url是这样的:/bloomtest/module/list/{projectId}
,大括号里的就是参数。
所以这里使用了正则去匹配我要的内容,表达式(?<=\{)(.+?)(?=\})
我搜的,具体我也不熟悉,后续再学习。
ReUtil.findAll
方法也是来自于 hutool 框架,可以查找到所有符合表达式的内容,返回是一个数组。
然后遍历这个数组,把里面的参数逐个拼接到一个空字符串里appendParamPath
:
String appendParamPath = ""; for (String i : resultFindAll) { appendParamPath = appendParamPath.concat("/" + paramMap.get(i)); }
去掉path后面的参数,还原path
因为前端传过来的 path 是/bloomtest/module/list/{projectId}
,需要去掉最后的/{projectId}
才可以使用。
List<String> list = Arrays.asList(request.getPath().split("/\\{")); String orginPath = list.get(0);
使用了字符串分割split
方法,返回的是一个String[]
数组,又通过Arrays.asList
进一步做了转化,就可以使用get(0)
获取第一个使用了,也就是/bloomtest/module/list
。
前面都齐了,就可以发送请求了,注意最终请求的 url 还是要拼接一下:request.getHost() + orginPath + appendParamPath
(3)请求体
这个最简单,前端传过来的 json 字符串直接传入即可:
if (request.getMethod().equals("post")) { String reqBody = request.getRequest(); String result = HttpRequest.post(url) .body(reqBody) .execute().body(); return JSONObject.parseObject(result); }
要注意的是,这里用的 JSONObject 是来自fastjson
,之前用 hutool 带的处理,会有报错,搞了好一会。
三、前端实现
我这里是整个功能开发完成后进行整理的,实际上,后端接口逻辑不是一次性写完的。先写好一个可以前端调得通的接口,然后一点点前后调试完成。
前端这里做的事情不多,在【发送】按钮上绑定一个点击实践,调用后端开发好的接口。
方法apiTestRun
内部,主要是处理请求入参,调用请求,处理返回即可:
红框里是调用接口的部分,前面的是处理入参。这里的 3 个判断是看目前点击了哪个 tab,然后传对应入参类型给接口。
接下来测试下功能OK。
四、修改遗留 bug
在测试功能的时候,发现了几个问题。大概表现都是因为前端参数赋值,或者没重置干净导致的。
增加和修改了一些代码,完整代码更新
前端:
https://github.com/wessonlan/bloomtest-web
后端
https://github.com/wessonlan/bloomtest-backend
以上就是springboot+vue测试平台接口定义及发送请求功能实现的详细内容,更多关于springboot+vue接口定义发送请求的资料请关注脚本之家其它相关文章!