diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index 6079f5c6fa..a3665e916c 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -234,7 +234,7 @@ public class MsHTTPSamplerProxy extends MsTestElement { //根据配置增加全局前后至脚本 JMeterScriptUtil.setScriptByHttpConfig(httpConfig, httpSamplerTree, config, useEnvironment, this.getEnvironmentId(), false); //增加误报、断言 - if (CollectionUtils.isNotEmpty(httpConfig.getErrorReportAssertions())) { + if (!config.isOperating() && CollectionUtils.isNotEmpty(httpConfig.getErrorReportAssertions())) { for (MsAssertions assertion : httpConfig.getErrorReportAssertions()) { assertion.toHashTree(httpSamplerTree, assertion.getHashTree(), config); } @@ -674,22 +674,22 @@ public class MsHTTPSamplerProxy extends MsTestElement { list.stream(). filter(KeyValue::isValid). filter(KeyValue::isEnable).forEach(keyValue -> { - try { - String value = StringUtils.isNotEmpty(keyValue.getValue()) && keyValue.getValue().startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue(); - HTTPArgument httpArgument = new HTTPArgument(keyValue.getName(), value); - if (keyValue.getValue() == null) { - httpArgument.setValue(""); - } - httpArgument.setAlwaysEncoded(keyValue.isUrlEncode()); - if (StringUtils.isNotBlank(keyValue.getContentType())) { - httpArgument.setContentType(keyValue.getContentType()); - } - arguments.addArgument(httpArgument); - } catch (Exception e) { + try { + String value = StringUtils.isNotEmpty(keyValue.getValue()) && keyValue.getValue().startsWith("@") ? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue()) : keyValue.getValue(); + HTTPArgument httpArgument = new HTTPArgument(keyValue.getName(), value); + if (keyValue.getValue() == null) { + httpArgument.setValue(""); + } + httpArgument.setAlwaysEncoded(keyValue.isUrlEncode()); + if (StringUtils.isNotBlank(keyValue.getContentType())) { + httpArgument.setContentType(keyValue.getContentType()); + } + arguments.addArgument(httpArgument); + } catch (Exception e) { - } - } - ); + } + } + ); return arguments; } 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 7315478908..00083eaf97 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 @@ -105,7 +105,7 @@ public class MockApiUtils { } else if (StringUtils.equalsIgnoreCase(type, "XML")) { if (bodyObj.containsKey("raw")) { String xmlStr = bodyObj.getString("raw"); - JSONObject matchObj = XMLUtils.XmlToJson(xmlStr); + JSONObject matchObj = XMLUtils.stringToJSONObject(xmlStr); returnJson = matchObj; } } else if (StringUtils.equalsIgnoreCase(type, "Raw")) { @@ -235,7 +235,7 @@ public class MockApiUtils { if (StringUtils.isNotEmpty(response)) { try { JSONObject respObj = JSONObject.parseObject(response); - if(respObj != null){ + if (respObj != null) { if (respObj.containsKey("body")) { String returnStr = ""; JSONObject bodyObj = respObj.getJSONObject("body"); @@ -311,15 +311,15 @@ public class MockApiUtils { } responseDTO.setReturnCode(code); } - if(respObj.containsKey("headers")){ + if (respObj.containsKey("headers")) { JSONArray jsonArray = respObj.getJSONArray("headers"); - Map headMap = new HashMap<>(); - for(int i = 0; i < jsonArray.size(); i ++){ + Map headMap = new HashMap<>(); + for (int i = 0; i < jsonArray.size(); i++) { JSONObject headObj = jsonArray.getJSONObject(i); - if(headObj.containsKey("name") && headObj.containsKey("value") && headObj.containsKey("enable")){ + if (headObj.containsKey("name") && headObj.containsKey("value") && headObj.containsKey("enable")) { boolean enable = headObj.getBoolean("enable"); - if(enable){ - headMap.put(headObj.getString("name"),headObj.getString("value")); + if (enable) { + headMap.put(headObj.getString("name"), headObj.getString("value")); } } } @@ -482,7 +482,7 @@ public class MockApiUtils { return returnJson; } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "text/xml")) { String xmlString = readXml(request); - JSONObject object = XMLUtils.XmlToJson(xmlString); + JSONObject object = XMLUtils.stringToJSONObject(xmlString); return object; } else if (StringUtils.startsWithIgnoreCase(request.getContentType(), "application/x-www-form-urlencoded")) { JSONObject object = new JSONObject(); diff --git a/backend/src/main/java/io/metersphere/commons/utils/HashTreeUtil.java b/backend/src/main/java/io/metersphere/commons/utils/HashTreeUtil.java index a28508f1cb..3a1c5156c5 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/HashTreeUtil.java +++ b/backend/src/main/java/io/metersphere/commons/utils/HashTreeUtil.java @@ -244,7 +244,7 @@ public class HashTreeUtil { if (envConfig == null) { return; } - if (envConfig.isUseErrorCode()) { + if (!config.isOperating() && envConfig.isUseErrorCode()) { List errorReportAssertion = HashTreeUtil.getErrorReportByProjectId(projectId); for (MsAssertions assertion : errorReportAssertion) { assertion.toHashTree(samplerHashTree, assertion.getHashTree(), config); 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 2769db4477..d4e70e4164 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java @@ -2,15 +2,20 @@ package io.metersphere.commons.utils; 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.*; public class XMLUtils { - public static void setExpandEntityReferencesFalse(DocumentBuilderFactory documentBuilderFactory){ + public static void setExpandEntityReferencesFalse(DocumentBuilderFactory documentBuilderFactory) { try { String FEATURE = null; FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing"; @@ -25,10 +30,11 @@ public class XMLUtils { documentBuilderFactory.setFeature(FEATURE, false); documentBuilderFactory.setXIncludeAware(false); documentBuilderFactory.setExpandEntityReferences(false); - }catch (Exception e){ + } catch (Exception e) { LogUtil.error(e); } } + private static void jsonToXmlStr(JSONObject jObj, StringBuffer buffer, StringBuffer tab) { Set> se = jObj.entrySet(); StringBuffer nowTab = new StringBuffer(tab.toString()); @@ -70,7 +76,7 @@ public class XMLUtils { // 传入完整的 xml 文本,转换成 json 对象 public static JSONObject XmlToJson(String xml) { JSONObject result = new JSONObject(); - if(xml == null) + if (xml == null) return null; List list = preProcessXml(xml); try { @@ -85,8 +91,8 @@ public class XMLUtils { // 预处理 xml 文本,转换成 tag + data 的列表 private static List preProcessXml(String xml) { int begin = xml.indexOf("?>"); - if(begin != -1) { - if(begin + 2 >= xml.length()) { + if (begin != -1) { + if (begin + 2 >= xml.length()) { return null; } xml = xml.substring(begin + 2); @@ -104,24 +110,24 @@ public class XMLUtils { // 传入预处理的列表,返回转换成功的 json 对象 private static Object XmlTagToJsonObject(List list) { - if(list == null || list.size() == 0) + if (list == null || list.size() == 0) return null; Stack tagStack = new Stack<>(); // tag 栈 Stack valueStack = new Stack<>(); // 数据栈 valueStack.push(new JSONObject()); // 最终结果将存放在第一个入栈的元素中 - for(String item : list) { + for (String item : list) { String beginTag = isBeginTag(item), endTag = isEndTag(item); // 判断当前 tag 是开始还是结尾 - if(beginTag != null) { + if (beginTag != null) { tagStack.push(beginTag); valueStack.push(new JSONObject()); - } else if(endTag != null) { - if(endTag.equals(tagStack.peek())) { // 是一对 tag + } else if (endTag != null) { + if (endTag.equals(tagStack.peek())) { // 是一对 tag Object topValue = valueStack.peek(); - if(topValue instanceof String) { // 栈顶是纯数据 xml 节点 + if (topValue instanceof String) { // 栈顶是纯数据 xml 节点 valueStack.pop(); } valueStack.pop(); - if(valueStack.peek() instanceof JSONObject) { + if (valueStack.peek() instanceof JSONObject) { ((JSONObject) valueStack.peek()).put(tagStack.peek(), topValue); } tagStack.pop(); @@ -130,7 +136,7 @@ public class XMLUtils { valueStack.push(item); } } - if(valueStack.empty()) + if (valueStack.empty()) return null; return valueStack.peek(); } @@ -155,4 +161,44 @@ public class XMLUtils { return null; } + public static Document stringToDocument(String xml) { + try { + return EngineSourceParserFactory.getDocument(new ByteArrayInputStream(xml.getBytes("utf-8"))); + } catch (Exception e) { + LogUtil.error(e); + return null; + } + } + + public static JSONObject stringToJSONObject(String xml) { + try { + return elementToJSONObject(stringToDocument(xml).getRootElement()); + } catch (Exception e) { + LogUtil.error(e); + return null; + } + } + + 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()) { + 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));// 将该一级节点放入该节点名称的属性对应的值中 + } + } + } + return result; + } } diff --git a/frontend/src/business/components/api/automation/report/components/RequestResult.vue b/frontend/src/business/components/api/automation/report/components/RequestResult.vue index f655982642..7d9a6385aa 100644 --- a/frontend/src/business/components/api/automation/report/components/RequestResult.vue +++ b/frontend/src/business/components/api/automation/report/components/RequestResult.vue @@ -15,11 +15,11 @@ -
- {{ errorCode }} + {{ baseErrorCode }}
@@ -57,7 +57,7 @@ $t('api_test.home_page.detail_card.unexecute') }} - + {{ $t('error_report_library.option.name') }} {{ $t('api_report.success') }} @@ -102,7 +102,10 @@ export default { scenarioName: String, indexNumber: Number, console: String, - errorCode: String, + errorCode: { + type: String, + default: "" + }, isActive: { type: Boolean, default: false @@ -110,6 +113,7 @@ export default { }, created() { this.showActive = this.isActive; + this.baseErrorCode = this.errorCode; }, data() { return { @@ -120,6 +124,7 @@ export default { return "#B8741A"; } }, + baseErrorCode: "", backgroundColor: { type: String, default() { @@ -133,14 +138,17 @@ export default { isActive() { this.showActive = this.isActive; }, + errorCode() { + this.baseErrorCode = this.errorCode; + }, request: { deep: true, handler(n) { if (this.request.errorCode) { - this.errorCode = this.request.errorCode; + this.baseErrorCode = this.request.errorCode; } else if (this.request.attachInfoMap && this.request.attachInfoMap.errorReportResult) { if (this.request.attachInfoMap.errorReportResult !== "") { - this.errorCode = this.request.attachInfoMap.errorReportResult; + this.baseErrorCode = this.request.attachInfoMap.errorReportResult; } } }, diff --git a/frontend/src/business/components/api/definition/ApiDefinition.vue b/frontend/src/business/components/api/definition/ApiDefinition.vue index a8149bbcd6..fe4171635b 100644 --- a/frontend/src/business/components/api/definition/ApiDefinition.vue +++ b/frontend/src/business/components/api/definition/ApiDefinition.vue @@ -44,7 +44,8 @@ right-content="CASE" >