fix(接口测试): 修复接口导入xml/raw格式未成功问题

--bug=1044007 --user=王旭 【接口测试】接口定义-导出接口,再导入到其他项目,接口数据不一致 https://www.tapd.cn/55049933/s/1553644
This commit is contained in:
WangXu10 2024-07-24 18:04:41 +08:00 committed by 刘瑞斌
parent 102dc1d8d6
commit 16177fedb6
4 changed files with 151 additions and 6 deletions

View File

@ -19,6 +19,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.springframework.http.MediaType;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -178,12 +179,12 @@ public class Swagger3ExportParser implements ExportParser<ApiExportResponse> {
private JSONObject buildContent(JSONObject respOrReq, List<JSONObject> schemas) { private JSONObject buildContent(JSONObject respOrReq, List<JSONObject> schemas) {
Hashtable<String, String> typeMap = new Hashtable<String, String>() {{ Hashtable<String, String> typeMap = new Hashtable<String, String>() {{
put(Body.BodyType.XML.name(), org.springframework.http.MediaType.APPLICATION_XML_VALUE); put(Body.BodyType.XML.name(), MediaType.APPLICATION_XML_VALUE);
put(Body.BodyType.JSON.name(), org.springframework.http.MediaType.APPLICATION_JSON_VALUE); put(Body.BodyType.JSON.name(), MediaType.APPLICATION_JSON_VALUE);
put(Body.BodyType.RAW.name(), "application/urlencoded"); put(Body.BodyType.RAW.name(), MediaType.TEXT_PLAIN_VALUE);
put(Body.BodyType.BINARY.name(), org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE); put(Body.BodyType.BINARY.name(), MediaType.APPLICATION_OCTET_STREAM_VALUE);
put(Body.BodyType.FORM_DATA.name(), org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE); put(Body.BodyType.FORM_DATA.name(), MediaType.MULTIPART_FORM_DATA_VALUE);
put(Body.BodyType.WWW_FORM.name(), org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE); put(Body.BodyType.WWW_FORM.name(), MediaType.APPLICATION_FORM_URLENCODED_VALUE);
}}; }};
Object bodyInfo = null; Object bodyInfo = null;
Object jsonInfo = null; Object jsonInfo = null;

View File

@ -14,6 +14,7 @@ import io.metersphere.api.dto.request.http.RestParam;
import io.metersphere.api.dto.request.http.body.*; import io.metersphere.api.dto.request.http.body.*;
import io.metersphere.api.dto.schema.JsonSchemaItem; import io.metersphere.api.dto.schema.JsonSchemaItem;
import io.metersphere.api.utils.JsonSchemaBuilder; import io.metersphere.api.utils.JsonSchemaBuilder;
import io.metersphere.api.utils.XMLUtil;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.constants.PropertyConstant; import io.metersphere.project.constants.PropertyConstant;
import io.metersphere.project.dto.environment.auth.NoAuth; import io.metersphere.project.dto.environment.auth.NoAuth;
@ -33,6 +34,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -217,6 +219,9 @@ public class Swagger3Parser extends ApiImportAbstractParser<ApiDefinitionImport>
formDataKV.setParamType(value.getType()); formDataKV.setParamType(value.getType());
formDataKV.setMinLength(value.getMinLength()); formDataKV.setMinLength(value.getMinLength());
formDataKV.setMaxLength(value.getMaxLength()); formDataKV.setMaxLength(value.getMaxLength());
if (StringUtils.equals(value.getType(), PropertyConstant.FILE)) {
formDataKV.setFiles(new ArrayList<>());
}
formDataKVS.add(formDataKV); formDataKVS.add(formDataKV);
} }
}); });
@ -286,6 +291,8 @@ public class Swagger3Parser extends ApiImportAbstractParser<ApiDefinitionImport>
body.setBodyType(Body.BodyType.XML.name()); body.setBodyType(Body.BodyType.XML.name());
XmlBody xml = new XmlBody(); XmlBody xml = new XmlBody();
//xml.setValue(XMLUtils.jsonToXmlStr(jsonValue)); //xml.setValue(XMLUtils.jsonToXmlStr(jsonValue));
String xmlBody = parseXmlBody(value.getSchema(), jsonSchemaItem);
xml.setValue(xmlBody);
body.setXmlBody(xml); body.setXmlBody(xml);
} }
case MediaType.MULTIPART_FORM_DATA_VALUE -> { case MediaType.MULTIPART_FORM_DATA_VALUE -> {
@ -297,6 +304,7 @@ public class Swagger3Parser extends ApiImportAbstractParser<ApiDefinitionImport>
case MediaType.TEXT_PLAIN_VALUE -> { case MediaType.TEXT_PLAIN_VALUE -> {
body.setBodyType(Body.BodyType.RAW.name()); body.setBodyType(Body.BodyType.RAW.name());
RawBody rawBody = new RawBody(); RawBody rawBody = new RawBody();
rawBody.setValue(value.getSchema().getExample().toString());
body.setRawBody(rawBody); body.setRawBody(rawBody);
} }
default -> body.setBodyType(Body.BodyType.NONE.name()); default -> body.setBodyType(Body.BodyType.NONE.name());
@ -328,6 +336,8 @@ public class Swagger3Parser extends ApiImportAbstractParser<ApiDefinitionImport>
body.setBodyType(Body.BodyType.XML.name()); body.setBodyType(Body.BodyType.XML.name());
XmlBody xml = new XmlBody(); XmlBody xml = new XmlBody();
//xml.setValue(XMLUtils.jsonToXmlStr(jsonValue)); //xml.setValue(XMLUtils.jsonToXmlStr(jsonValue));
String xmlBody = parseXmlBody(value.getSchema(), jsonSchemaItem);
xml.setValue(xmlBody);
body.setXmlBody(xml); body.setXmlBody(xml);
} }
case MediaType.APPLICATION_FORM_URLENCODED_VALUE -> { case MediaType.APPLICATION_FORM_URLENCODED_VALUE -> {
@ -344,12 +354,38 @@ public class Swagger3Parser extends ApiImportAbstractParser<ApiDefinitionImport>
case MediaType.TEXT_PLAIN_VALUE -> { case MediaType.TEXT_PLAIN_VALUE -> {
body.setBodyType(Body.BodyType.RAW.name()); body.setBodyType(Body.BodyType.RAW.name());
RawBody rawBody = new RawBody(); RawBody rawBody = new RawBody();
rawBody.setValue(value.getSchema().getExample().toString());
body.setRawBody(rawBody); body.setRawBody(rawBody);
} }
default -> body.setBodyType(Body.BodyType.NONE.name()); default -> body.setBodyType(Body.BodyType.NONE.name());
} }
} }
private String parseXmlBody(Schema schema, JsonSchemaItem jsonSchemaItem) {
if (jsonSchemaItem instanceof JsonSchemaItem) {
if (MapUtils.isNotEmpty(jsonSchemaItem.getProperties())) {
if (jsonSchemaItem.getProperties().keySet().size() > 1) {
JSONObject object = new JSONObject();
if (StringUtils.isNotBlank(schema.get$ref())) {
String ref = schema.get$ref();
if (ref.split("/").length > 3) {
ref = ref.replace("#/components/schemas/", StringUtils.EMPTY);
object.put(ref, jsonSchemaItem.getProperties());
return XMLUtil.jsonToPrettyXml(object);
}
}
}
}
return "";
} else {
JSONObject object = new JSONObject();
if (StringUtils.isNotBlank(schema.getName())) {
object.put(schema.getName(), schema.getExample());
}
return XMLUtil.jsonToPrettyXml(object);
}
}
private ApiDefinitionImportDetail buildSwaggerApiDefinition(Operation operation, String path, String private ApiDefinitionImportDetail buildSwaggerApiDefinition(Operation operation, String path, String
method, ImportRequest importRequest) { method, ImportRequest importRequest) {
String name; String name;
@ -511,6 +547,9 @@ public class Swagger3Parser extends ApiImportAbstractParser<ApiDefinitionImport>
jsonSchemaProperties.put(key, item); jsonSchemaProperties.put(key, item);
}); });
} }
if (StringUtils.isNotBlank(modelByRef.getType())) {
jsonSchemaItem.setType(modelByRef.getType());
}
jsonSchemaItem.setProperties(jsonSchemaProperties); jsonSchemaItem.setProperties(jsonSchemaProperties);
yield jsonSchemaItem; yield jsonSchemaItem;
} }

View File

@ -5,11 +5,16 @@ import io.metersphere.sdk.util.XMLUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute; import org.dom4j.Attribute;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -21,6 +26,8 @@ import java.util.regex.Pattern;
*/ */
public class XMLUtil { public class XMLUtil {
private static final String ENCODING = "UTF-8";
@Nullable @Nullable
public static String delXmlHeader(String xml) { public static String delXmlHeader(String xml) {
int begin = xml.indexOf("?>"); int begin = xml.indexOf("?>");
@ -94,4 +101,100 @@ public class XMLUtil {
} }
return result; return result;
} }
/**
* JSON对象转xml字符串
*
* @param json JSON对象
* @return xml字符串
*/
public static String jsonToPrettyXml(JSONObject json) {
Document document = jsonToDocument(json);
/* 格式化xml */
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置缩进为4个空格
format.setIndent(StringUtils.SPACE);
format.setIndentSize(4);
StringWriter formatXml = new StringWriter();
XMLWriter writer = new XMLWriter(formatXml, format);
try {
writer.write(document);
} catch (IOException e) {
LogUtils.error("This object can not convert to xml", e);
}
return formatXml.toString();
}
/**
* JSON对象转Document对象
*
* @param json JSON对象
* @return Document对象
*/
public static Document jsonToDocument(JSONObject json) {
Document document = DocumentHelper.createDocument();
document.setXMLEncoding(ENCODING);
setDocument(json, document);
return document;
}
private static void setDocument(JSONObject json, Document document) {
for (String key : json.keySet()) {
if (json.get(key) instanceof LinkedList<?>) {
for (Object o : ((LinkedList<?>) json.get(key))) {
setDocument((JSONObject) o, document);
}
} else {
Element root = jsonToElement(json.get(key), key);
document.add(root);
}
}
}
/**
* JSON对象转Element对象
*
* @param json JSON对象
* @param nodeName 节点名称
* @return Element对象
*/
public static Element jsonToElement(Object json, String nodeName) {
Element node = DocumentHelper.createElement(nodeName);
if (json instanceof JSONObject) {
delObject(json, node);
}
if (json instanceof List<?>) {
((List<?>) json).forEach(t -> {
jsonToElement(t, nodeName);
});
}
if (json instanceof String) {
Element element = DocumentHelper.createElement(json.toString());
element.setText(json.toString());
node.add(element);
}
return node;
}
private static void delObject(Object json, Element node) {
for (String key : ((JSONObject) json).keySet()) {
Object child = ((JSONObject) json).get(key);
if (child instanceof JSONObject) {
node.add(jsonToElement(((JSONObject) json).get(key), key));
} else if (child instanceof LinkedList<?>) {
((LinkedList<?>) child).forEach(t -> {
node.add(jsonToElement(t, key));
});
} else {
if (StringUtils.equals(key, "example")) {
node.setText(((JSONObject) json).get(key).toString());
}
}
}
}
} }

View File

@ -32,4 +32,6 @@ public class PropertyConstant {
public final static String MAX_ITEMS = "maxItems"; public final static String MAX_ITEMS = "maxItems";
public final static String MIN_ITEMS = "minItems"; public final static String MIN_ITEMS = "minItems";
public final static String FILE = "file";
} }