feat(接口测试): 修复部分Xml转JSON无法解析的问题

--bug=1016192 --user=宋天阳 【接口测试】tcp的mock请求,两个mock期望都返回了一个响应内容
https://www.tapd.cn/55049933/s/1232195
This commit is contained in:
song-tianyang 2022-08-24 13:40:11 +08:00 committed by 刘瑞斌
parent b787dc19c1
commit 698328ab7f
4 changed files with 63 additions and 47 deletions

View File

@ -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,9 +140,9 @@ public class TcpTreeTableDataParser {
continue;
}
}
}
isMatch = true;
}
}
return isMatch;
}

View File

@ -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())) {

View File

@ -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> 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<String, String> headerMap, RequestMockParams requestMockParams, HttpServletResponse response) {
public String updateHttpServletResponse(String projectId, MockExpectConfigResponse finalExpectConfig, String url, Map<String, String> 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<String, String> 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<ProjectApplication> projectApplications = projectApplicationService.selectByExample(pae);
List<ProjectApplication> projectApplicationsByMockTcpPort = projectApplicationService.selectByExample(pae);
List<ProjectApplication> 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<String> projectIds = projectApplications.stream().map(ProjectApplication::getProjectId).collect(Collectors.toList());
List<Project> projectList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(projectIds)) {
@ -1176,7 +1181,8 @@ public class MockConfigService {
}
} else if (isXMLMessage && StringUtils.equalsIgnoreCase(reportType, "xml")) {
if (requestJson.containsKey("xmlDataStruct")) {
JSONObject sourceObj = XMLUtils.XmlToJson(message);
JSONObject sourceObj = XMLUtils.xmlStringToJSONObject(message);
if (!sourceObj.isEmpty()) {
try {
List<TcpTreeTableDataStruct> tcpDataList = JSONArray.parseArray(requestJson.getString("xmlDataStruct"), TcpTreeTableDataStruct.class);
isMatch = TcpTreeTableDataParser.isMatchTreeTableData(sourceObj, tcpDataList);
@ -1184,6 +1190,7 @@ public class MockConfigService {
LogUtil.error(e);
}
}
}
} else if (StringUtils.equalsIgnoreCase(reportType, "raw")) {
if (requestJson.containsKey("rawDataStruct")) {
String rawDataStruct = requestJson.getString("rawDataStruct");

View File

@ -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<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
result.put(attr.getName(), attr.getValue());
}
// 递归遍历当前节点所有的子节点
List<Element> 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;