From 698328ab7fb7988cc71d922406471193b3fce451 Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Wed, 24 Aug 2022 13:40:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86Xml=E8=BD=ACJSON=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=A7=A3=E6=9E=90=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1016192 --user=宋天阳 【接口测试】tcp的mock请求,两个mock期望都返回了一个响应内容 https://www.tapd.cn/55049933/s/1232195 --- .../parse/TcpTreeTableDataParser.java | 16 ++++-- .../api/mock/utils/MockApiUtils.java | 7 ++- .../api/service/MockConfigService.java | 55 +++++++++++-------- .../metersphere/commons/utils/XMLUtils.java | 32 +++++------ 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/parse/TcpTreeTableDataParser.java b/backend/src/main/java/io/metersphere/api/dto/automation/parse/TcpTreeTableDataParser.java index 93cd306c70..38847a23f2 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/parse/TcpTreeTableDataParser.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/parse/TcpTreeTableDataParser.java @@ -94,7 +94,7 @@ public class TcpTreeTableDataParser { boolean isMatch = false; for (TcpTreeTableDataStruct dataStruct : tcpDataList) { - if(isMatch){ + if (isMatch) { break; } String key = dataStruct.getName(); @@ -111,16 +111,22 @@ public class TcpTreeTableDataParser { } else if (sourceObjItem instanceof JSONArray) { if (!CollectionUtils.isEmpty(dataStruct.getChildren())) { JSONArray jsonArray = (JSONArray) sourceObjItem; - for (int i = 0; i < jsonArray.size(); i ++){ + boolean hasMatchAny = false; + for (int i = 0; i < jsonArray.size(); i++) { Object itemObj = jsonArray.get(i); - if(itemObj instanceof JSONObject){ + if (itemObj instanceof JSONObject) { if (!isMatchTreeTableData((JSONObject) itemObj, dataStruct.getChildren())) { continue; + } else { + hasMatchAny = true; } - }else { + } else { continue; } } + if (!hasMatchAny) { + continue; + } } else { continue; } @@ -134,8 +140,8 @@ public class TcpTreeTableDataParser { continue; } } + isMatch = true; } - isMatch = true; } return isMatch; diff --git a/backend/src/main/java/io/metersphere/api/mock/utils/MockApiUtils.java b/backend/src/main/java/io/metersphere/api/mock/utils/MockApiUtils.java index 61850e9406..01ab727f47 100644 --- a/backend/src/main/java/io/metersphere/api/mock/utils/MockApiUtils.java +++ b/backend/src/main/java/io/metersphere/api/mock/utils/MockApiUtils.java @@ -104,7 +104,7 @@ public class MockApiUtils { } else if (StringUtils.equalsIgnoreCase(type, "XML")) { if (bodyObj.containsKey("raw")) { String xmlStr = bodyObj.getString("raw"); - JSONObject matchObj = XMLUtils.stringToJSONObject(xmlStr); + JSONObject matchObj = XMLUtils.xmlStringToJSONObject(xmlStr); returnJson = matchObj; } } else if (StringUtils.equalsIgnoreCase(type, "Raw")) { @@ -415,7 +415,7 @@ public class MockApiUtils { return returnJson; } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "text/xml")) { String xmlString = readXml(request); - JSONObject object = XMLUtils.stringToJSONObject(xmlString); + JSONObject object = XMLUtils.xmlStringToJSONObject(xmlString); return object; } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "application/x-www-form-urlencoded")) { JSONObject object = new JSONObject(); @@ -655,6 +655,9 @@ public class MockApiUtils { } public static boolean isValueMatch(String requestParam, MockConfigRequestParams params) { + if (StringUtils.isBlank(params.getCondition())) { + params.setCondition(MockParamConditionEnum.VALUE_EQUALS.name()); + } if (StringUtils.equals(params.getCondition(), MockParamConditionEnum.VALUE_EQUALS.name())) { return StringUtils.equals(requestParam, params.getValue()); } else if (StringUtils.equals(params.getCondition(), MockParamConditionEnum.VALUE_NOT_EQUALS.name())) { diff --git a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java index 1200580ef4..4959895032 100644 --- a/backend/src/main/java/io/metersphere/api/service/MockConfigService.java +++ b/backend/src/main/java/io/metersphere/api/service/MockConfigService.java @@ -24,7 +24,6 @@ import io.metersphere.base.mapper.ext.ExtMockExpectConfigMapper; import io.metersphere.commons.constants.ProjectApplicationType; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; -import io.metersphere.jmeter.utils.ScriptEngineUtils; import io.metersphere.i18n.Translator; import io.metersphere.service.ProjectApplicationService; import org.apache.commons.collections.CollectionUtils; @@ -41,7 +40,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import java.io.*; +import java.io.ByteArrayInputStream; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -390,7 +389,7 @@ public class MockConfigService { if (StringUtils.equalsAnyIgnoreCase(type, "Form Data", "WWW_FORM") && expectBodyObject.containsKey("kvs")) { JSONArray kvsArr = expectBodyObject.getJSONArray("kvs"); List mockConfigRequestParams = MockApiUtils.getParamsByJSONArray(kvsArr); - if(CollectionUtils.isNotEmpty(mockConfigRequestParams)){ + if (CollectionUtils.isNotEmpty(mockConfigRequestParams)) { if (!MockApiUtils.checkParamsCompliance(jsonArray, mockConfigRequestParams, StringUtils.equals(paramsFilterType, "And"))) { return false; } @@ -705,7 +704,7 @@ public class MockConfigService { return returnModel; } - public String updateHttpServletResponse(String projectId,MockExpectConfigResponse finalExpectConfig, String url, Map headerMap, RequestMockParams requestMockParams, HttpServletResponse response) { + public String updateHttpServletResponse(String projectId, MockExpectConfigResponse finalExpectConfig, String url, Map headerMap, RequestMockParams requestMockParams, HttpServletResponse response) { String returnStr = ""; try { //设置响应头和响应码 @@ -737,7 +736,7 @@ public class MockConfigService { if (responseJsonObj.containsKey("usePostScript")) { useScript = responseJsonObj.getBoolean("usePostScript"); } - returnStr = mockApiUtils.getResultByResponseResult(projectId,responseJsonObj.getJSONObject("body"), url, headerMap, requestMockParams, useScript); + returnStr = mockApiUtils.getResultByResponseResult(projectId, responseJsonObj.getJSONObject("body"), url, headerMap, requestMockParams, useScript); } if (responseJsonObj.containsKey("httpCode")) { int httpCodeNum = 500; @@ -998,18 +997,18 @@ public class MockConfigService { JSON paramJson = MockApiUtils.getPostParamMap(request); JSONObject parameterObject = MockApiUtils.getParameterJsonObject(request); for (ApiDefinitionWithBLOBs api : aualifiedApiList) { - if(StringUtils.isEmpty(returnStr)){ + if (StringUtils.isEmpty(returnStr)) { RequestMockParams mockParams = MockApiUtils.getParams(urlSuffix, api.getPath(), parameterObject, paramJson, true); MockConfigResponse mockConfigData = this.findByApiId(api.getId()); MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), mockParams); if (finalExpectConfig != null) { - returnStr = this.updateHttpServletResponse(project.getId(),finalExpectConfig, url, requestHeaderMap, mockParams, response); - }else { + returnStr = this.updateHttpServletResponse(project.getId(), finalExpectConfig, url, requestHeaderMap, mockParams, response); + } else { returnStr = this.getApiDefinitionResponse(api, response); } } } - if(CollectionUtils.isNotEmpty(aualifiedApiList)){ + if (CollectionUtils.isNotEmpty(aualifiedApiList)) { matchApi = true; } } @@ -1042,21 +1041,21 @@ public class MockConfigService { JSONObject parameterObject = MockApiUtils.getParameterJsonObject(request); for (ApiDefinitionWithBLOBs api : aualifiedApiList) { - if(StringUtils.isEmpty(returnStr)){ + if (StringUtils.isEmpty(returnStr)) { RequestMockParams paramMap = MockApiUtils.getParams(urlSuffix, api.getPath(), parameterObject, paramJson, false); MockConfigResponse mockConfigData = this.findByApiId(api.getId()); if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) { MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(requestHeaderMap, mockConfigData.getMockExpectConfigList(), paramMap); if (finalExpectConfig != null) { - returnStr = this.updateHttpServletResponse(project.getId(),finalExpectConfig, url, requestHeaderMap, paramMap, response); - }else { + returnStr = this.updateHttpServletResponse(project.getId(), finalExpectConfig, url, requestHeaderMap, paramMap, response); + } else { returnStr = this.getApiDefinitionResponse(api, response); } } } } - if(CollectionUtils.isNotEmpty(aualifiedApiList)){ + if (CollectionUtils.isNotEmpty(aualifiedApiList)) { matchApi = true; } } @@ -1076,7 +1075,7 @@ public class MockConfigService { response.setStatus(responseDTO.getReturnCode()); if (MapUtils.isNotEmpty(responseDTO.getHeaders())) { for (Map.Entry entry : responseDTO.getHeaders().entrySet()) { - if(StringUtils.isNotEmpty(entry.getKey())){ + if (StringUtils.isNotEmpty(entry.getKey())) { response.setHeader(entry.getKey(), entry.getValue()); } } @@ -1134,11 +1133,17 @@ public class MockConfigService { public MockExpectConfigDTO matchTcpMockExpect(String message, int port) { ProjectApplicationExample pae = new ProjectApplicationExample(); - pae.createCriteria().andTypeEqualTo(ProjectApplicationType.MOCK_TCP_OPEN.name()) - .andTypeValueEqualTo(String.valueOf(true)); - pae.or().andTypeEqualTo(ProjectApplicationType.MOCK_TCP_PORT.name()) + pae.createCriteria().andTypeEqualTo(ProjectApplicationType.MOCK_TCP_PORT.name()) .andTypeValueEqualTo(String.valueOf(port)); - List projectApplications = projectApplicationService.selectByExample(pae); + List projectApplicationsByMockTcpPort = projectApplicationService.selectByExample(pae); + List projectApplications = new ArrayList<>(); + for (ProjectApplication projectApp : projectApplicationsByMockTcpPort) { + pae.clear(); + pae.createCriteria().andProjectIdEqualTo(projectApp.getProjectId()) + .andTypeEqualTo(ProjectApplicationType.MOCK_TCP_OPEN.name()) + .andTypeValueEqualTo(String.valueOf(true)); + projectApplications.addAll(projectApplicationService.selectByExample(pae)); + } List projectIds = projectApplications.stream().map(ProjectApplication::getProjectId).collect(Collectors.toList()); List projectList = new ArrayList<>(); if (CollectionUtils.isNotEmpty(projectIds)) { @@ -1176,12 +1181,14 @@ public class MockConfigService { } } else if (isXMLMessage && StringUtils.equalsIgnoreCase(reportType, "xml")) { if (requestJson.containsKey("xmlDataStruct")) { - JSONObject sourceObj = XMLUtils.XmlToJson(message); - try { - List tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"), TcpTreeTableDataStruct.class); - isMatch = TcpTreeTableDataParser.isMatchTreeTableData(sourceObj, tcpDataList); - } catch (Exception e) { - LogUtil.error(e); + JSONObject sourceObj = XMLUtils.xmlStringToJSONObject(message); + if (!sourceObj.isEmpty()) { + try { + List tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"), TcpTreeTableDataStruct.class); + isMatch = TcpTreeTableDataParser.isMatchTreeTableData(sourceObj, tcpDataList); + } catch (Exception e) { + LogUtil.error(e); + } } } } else if (StringUtils.equalsIgnoreCase(reportType, "raw")) { diff --git a/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java b/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java index d4e70e4164..a7f52b7c7b 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java @@ -4,14 +4,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.metersphere.performance.parse.EngineSourceParserFactory; import org.apache.commons.lang3.StringUtils; -import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.util.*; -import java.util.regex.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class XMLUtils { @@ -170,7 +170,7 @@ public class XMLUtils { } } - public static JSONObject stringToJSONObject(String xml) { + public static JSONObject xmlStringToJSONObject(String xml) { try { return elementToJSONObject(stringToDocument(xml).getRootElement()); } catch (Exception e) { @@ -181,22 +181,22 @@ public class XMLUtils { public static JSONObject elementToJSONObject(Element node) { JSONObject result = new JSONObject(); - // 当前节点的名称、文本内容和属性 - List listAttr = node.attributes();// 当前节点的所有属性的list - for (Attribute attr : listAttr) {// 遍历当前节点的所有属性 - result.put(attr.getName(), attr.getValue()); - } - // 递归遍历当前节点所有的子节点 + List listElement = node.elements();// 所有一级子节点的list if (!listElement.isEmpty()) { + JSONArray jsonArray = new JSONArray(); for (Element e : listElement) {// 遍历所有一级子节点 - if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点 - result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待 - else { - if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性 - result.put(e.getName(), new JSONArray());// 没有则创建 - ((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中 - } + JSONObject jsonObject = elementToJSONObject(e); + jsonArray.add(jsonObject); + } + if (jsonArray.size() == 1) { + result.put(node.getName(), jsonArray.getJSONObject(0)); + } else { + result.put(node.getName(), jsonArray); + } + } else { + if (!StringUtils.isAllBlank(node.getName(), node.getText())) { + result.put(node.getName(), node.getText()); } } return result;