diff --git a/.gitignore b/.gitignore
index 165db4e885..309a8126a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,8 @@ yarn-debug.log*
yarn-error.log*
# Editor directories and files
-.idea
+.idea/*
+!.idea/icon.png
**/*.iml
.vscode
*.suo
diff --git a/.idea/icon.png b/.idea/icon.png
new file mode 100644
index 0000000000..15fb97a693
Binary files /dev/null and b/.idea/icon.png differ
diff --git a/Jenkinsfile b/Jenkinsfile
index 994ddca141..653ff55bbd 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -13,6 +13,9 @@ pipeline {
stage('Build/Test') {
steps {
configFileProvider([configFile(fileId: 'metersphere-maven', targetLocation: 'settings.xml')]) {
+ sh "cd frontend"
+ sh "yarn install"
+ sh "cd .."
sh "mvn clean package --settings ./settings.xml"
}
}
diff --git a/backend/pom.xml b/backend/pom.xml
index be89a74d2e..c54fc88b7c 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -283,6 +283,13 @@
2.0.22
+
+
+ org.codehaus.groovy
+ groovy-jsr223
+ 2.5.10
+
+
org.graalvm.sdk
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java
index a830b1d656..8655751191 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger2Parser.java
@@ -149,6 +149,14 @@ public class Swagger2Parser extends SwaggerAbstractParser {
return getBodyType(contentType);
}
+ private String getResponseBodyType(Operation operation) {
+ if (CollectionUtils.isEmpty(operation.getProduces())) {
+ return Body.JSON;
+ }
+ String contentType = operation.getProduces().get(0);
+ return getBodyType(contentType);
+ }
+
private void parsePathParameters(Parameter parameter, List rests) {
PathParameter pathParameter = (PathParameter) parameter;
rests.add(new KeyValue(pathParameter.getName(), "", getDefaultStringValue(parameter.getDescription())));
@@ -175,14 +183,17 @@ public class Swagger2Parser extends SwaggerAbstractParser {
msResponse.getBody().setKvs(new ArrayList<>());
msResponse.setHeaders(new ArrayList<>());
msResponse.setType(RequestType.HTTP);
- msResponse.getBody().setType(getBodyType(operation));
+ msResponse.getBody().setType(getResponseBodyType(operation));
// todo 状态码要调整?
msResponse.setStatusCode(new ArrayList<>());
- if (responses != null) {
+ if (responses != null && responses.size() > 0) {
responses.forEach((responseCode, response) -> {
msResponse.getStatusCode().add(new KeyValue(responseCode, responseCode));
+ String body = parseSchema(response.getResponseSchema());
+ if (StringUtils.isNotBlank(body)) {
+ msResponse.getBody().setRaw(body);
+ }
parseResponseHeader(response, msResponse.getHeaders());
- parseResponseBodyParameters(response, msResponse.getBody());
});
}
return msResponse;
@@ -197,10 +208,6 @@ public class Swagger2Parser extends SwaggerAbstractParser {
}
}
- private void parseResponseBodyParameters(Response response, Body body) {
- body.setRaw(parseSchema(response.getResponseSchema()));
- }
-
private void parseRequestBodyParameters(Parameter parameter, Body body) {
BodyParameter bodyParameter = (BodyParameter) parameter;
body.setRaw(parseSchema(bodyParameter.getSchema()));
diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java
index 5e96e31159..dd25a0c8b5 100644
--- a/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java
+++ b/backend/src/main/java/io/metersphere/api/dto/definition/parse/Swagger3Parser.java
@@ -26,12 +26,15 @@ import io.swagger.v3.oas.models.parameters.*;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
+import net.sf.saxon.ma.json.XMLToJsonFn;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
+import org.fife.ui.rsyntaxtextarea.parser.XmlParser;
import org.springframework.http.HttpMethod;
import java.io.InputStream;
+import java.math.BigDecimal;
import java.util.*;
@@ -334,6 +337,16 @@ public class Swagger3Parser extends SwaggerAbstractParser {
} else if (schema instanceof BinarySchema) {
return getDefaultValueByPropertyType(schema);
} else {
+ if(schema.getType() != null) { // 特判属性不是对象的情况,直接将基本类型赋值进去
+ if(StringUtils.equals(schema.getType(), "string")) {
+ String example = (String) schema.getExample();
+ return example == null ? "" : example;
+ } else if(StringUtils.equals(schema.getType(), "boolean")) {
+ return schema.getExample();
+ } else if(StringUtils.equals(schema.getType(), "double")) {
+ return schema.getExample();
+ }
+ }
Object propertiesResult = parseSchemaProperties(schema, refSet, infoMap);
return propertiesResult == null ? getDefaultValueByPropertyType(schema) : propertiesResult;
}
@@ -432,7 +445,9 @@ public class Swagger3Parser extends SwaggerAbstractParser {
JSONObject requestBody = buildRequestBody(requestObject);
swaggerApiInfo.setRequestBody(requestBody);
// 设置响应体
- swaggerApiInfo.setResponses(new JSONObject());
+// JSONObject reponseObject = JSON.parseObject(apiDefinition.getResponse());
+// swaggerApiInfo.setResponses(buildResponseBody(reponseObject));
+ //.....
// 设置请求参数列表
List paramsList = buildParameters(requestObject);
swaggerApiInfo.setParameters(paramsList);
@@ -459,6 +474,9 @@ public class Swagger3Parser extends SwaggerAbstractParser {
if(params != null) {
for(int i = 0; i < params.size(); ++i) {
JSONObject param = params.getJSONObject(i); // 对于每个参数:
+ if(param.get("name") == null || StringUtils.isEmpty(((String) param.get("name")))) {
+ continue;
+ } // 否则无参数的情况,可能多出一行空行
SwaggerParams swaggerParam = new SwaggerParams();
swaggerParam.setIn(typeMap.get(type)); // 利用 map,根据 request 的 key 设置对应的参数类型
swaggerParam.setDescription((String) param.get("description"));
@@ -480,9 +498,20 @@ public class Swagger3Parser extends SwaggerAbstractParser {
put("Form Data", org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE);
put("WWW_FORM", org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE);
}};
+ JSONObject bodyInfo = new JSONObject();
+ if(request.getJSONObject("body") != null && request.getJSONObject("body").containsKey("raw")) {
+ String bodyType = request.getJSONObject("body").getString("type");
+ if(bodyType.equals("JSON")) {
+ bodyInfo = buildRequestBodyJsonInfo(request.getJSONObject("body").getJSONObject("raw"));
+ } else if(bodyType.equals("XML")) {
+ String xmlText = request.getJSONObject("body").getString("raw");
+ JSONObject xmlToJson = XMLUtils.XmlToJson(xmlText);
+ bodyInfo = buildRequestBodyJsonInfo(xmlToJson);
+ }
+ }
String type = request.getJSONObject("body").getString("type");
JSONObject requestBody = new JSONObject();
- JSONObject schema = new JSONObject();
+ JSONObject schema = bodyInfo; // 需要转换导出
JSONObject typeName = new JSONObject();
schema.put("type", null);
schema.put("format", null);
@@ -494,4 +523,55 @@ public class Swagger3Parser extends SwaggerAbstractParser {
requestBody.put("content", content);
return requestBody;
}
+
+ // 将请求体中的一个 json 对象转换成 swagger 格式的 json 对象返回
+ private JSONObject buildRequestBodyJsonInfo(JSONObject requestBody) {
+ JSONObject schema = new JSONObject();
+ schema.put("type", "object");
+ JSONObject properties = buildSchema(requestBody);
+ schema.put("properties", properties);
+ return schema;
+ }
+
+ // 设置一个 json 对象的属性在 swagger 格式中的类型、值
+ private JSONObject buildSchema(JSONObject requestBody) {
+ JSONObject schema = new JSONObject();
+ for(String key : requestBody.keySet()) {
+ Object param = requestBody.get(key);
+ JSONObject parsedParam = new JSONObject();
+ if(param instanceof java.lang.String) {
+ parsedParam.put("type", "string");
+ parsedParam.put("example", param == null? "" : param);
+ } else if(param instanceof java.lang.Integer) {
+ parsedParam.put("type", "integer");
+ parsedParam.put("format", "int64");
+ parsedParam.put("example", param);
+ } else if(param instanceof JSONObject) {
+ parsedParam = buildRequestBodyJsonInfo((JSONObject) param);
+ } else if(param instanceof java.lang.Boolean) {
+ parsedParam.put("type", "boolean");
+ parsedParam.put("example", param);
+ } else if(param instanceof java.math.BigDecimal) { // double 类型会被 fastJson 转换为 BigDecimal
+ parsedParam.put("type", "double");
+ parsedParam.put("example", param);
+ } else { // JSONOArray
+ parsedParam.put("type", "array");
+ JSONObject item = new JSONObject();
+ if(((JSONArray) param).size() > 0) {
+ if(((JSONArray) param).get(0) instanceof JSONObject) { ///
+ item = buildRequestBodyJsonInfo((JSONObject) ((JSONArray) param).get(0));
+ }
+ }
+ parsedParam.put("items", item);
+ }
+ schema.put(key, parsedParam);
+ }
+ return schema;
+ }
+
+ private JSONObject buildResponseBody(JSONObject reponse) {
+ JSONObject responseBody = new JSONObject();
+
+ return responseBody;
+ }
}
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 2d88dde7f5..d70423500e 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
@@ -130,7 +130,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
}
// 1.8 之前历史数据
- if(StringUtils.isEmpty(this.getProjectId()) && config.getConfig()!= null && !config.getConfig().isEmpty()){
+ if (StringUtils.isEmpty(this.getProjectId()) && config.getConfig() != null && !config.getConfig().isEmpty()) {
this.setProjectId("historyProjectID");
}
@@ -154,10 +154,11 @@ public class MsHTTPSamplerProxy extends MsTestElement {
}
URL urlObject = new URL(url);
sampler.setDomain(URLDecoder.decode(urlObject.getHost(), "UTF-8"));
- if (urlObject.getPort() > 0 && urlObject.getPort() != 10990 && StringUtils.isNotEmpty(this.getPort()) && this.getPort().startsWith("${")) {
- sampler.setPort(urlObject.getPort());
- } else {
+
+ if (urlObject.getPort() > 0 && urlObject.getPort() == 10990 && StringUtils.isNotEmpty(this.getPort()) && this.getPort().startsWith("${")) {
sampler.setProperty("HTTPSampler.port", this.getPort());
+ } else {
+ sampler.setPort(urlObject.getPort());
}
sampler.setProtocol(urlObject.getProtocol());
sampler.setPath(urlObject.getPath());
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
index 4cce2bef3a..9f969416cb 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
@@ -21,10 +21,7 @@ import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.parse.ApiImportParser;
import io.metersphere.base.domain.*;
-import io.metersphere.base.mapper.ApiScenarioMapper;
-import io.metersphere.base.mapper.ApiScenarioReportMapper;
-import io.metersphere.base.mapper.TestCaseReviewScenarioMapper;
-import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
+import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException;
@@ -61,6 +58,8 @@ import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiAutomationService {
+ @Resource
+ ApiScenarioModuleMapper apiScenarioModuleMapper;
@Resource
private ExtScheduleMapper extScheduleMapper;
@Resource
@@ -242,9 +241,14 @@ public class ApiAutomationService {
} else {
scenario.setUserId(request.getUserId());
}
- if (StringUtils.isEmpty(request.getApiScenarioModuleId())) {
- scenario.setApiScenarioModuleId("root");
- scenario.setModulePath("/默认模块");
+ if (StringUtils.isEmpty(request.getApiScenarioModuleId()) || StringUtils.isEmpty(request.getModulePath()) || "default-module".equals(request.getApiScenarioModuleId())) {
+ ApiScenarioModuleExample example = new ApiScenarioModuleExample();
+ example.createCriteria().andProjectIdEqualTo(request.getProjectId()).andNameEqualTo("默认模块");
+ List modules = apiScenarioModuleMapper.selectByExample(example);
+ if (CollectionUtils.isNotEmpty(modules)) {
+ scenario.setApiScenarioModuleId(modules.get(0).getId());
+ scenario.setModulePath(modules.get(0).getName());
+ }
}
return scenario;
}
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
index af9f596c12..435846891b 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
@@ -94,6 +94,8 @@ public class ApiDefinitionService {
private ApiTestEnvironmentService environmentService;
@Resource
private EsbApiParamService esbApiParamService;
+ @Resource
+ ApiModuleMapper apiModuleMapper;
private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24);
@@ -262,9 +264,14 @@ public class ApiDefinitionService {
test.setEnvironmentId(request.getEnvironmentId());
test.setUserId(request.getUserId());
test.setTags(request.getTags());
- if (StringUtils.isEmpty(request.getModuleId())) {
- test.setModulePath("/默认模块");
- test.setModuleId("root");
+ if (StringUtils.isEmpty(request.getModulePath()) || StringUtils.isEmpty(request.getModuleId()) || "default-module".equals(request.getModuleId())) {
+ ApiModuleExample example = new ApiModuleExample();
+ example.createCriteria().andProjectIdEqualTo(test.getProjectId()).andProtocolEqualTo(test.getProtocol()).andNameEqualTo("默认模块");
+ List modules = apiModuleMapper.selectByExample(example);
+ if (CollectionUtils.isNotEmpty(modules)) {
+ test.setModuleId(modules.get(0).getId());
+ test.setModulePath(modules.get(0).getName());
+ }
}
apiDefinitionMapper.updateByPrimaryKeySelective(test);
return test;
@@ -290,9 +297,14 @@ public class ApiDefinitionService {
test.setStatus(APITestStatus.Underway.name());
test.setModulePath(request.getModulePath());
test.setModuleId(request.getModuleId());
- if (StringUtils.isEmpty(request.getModuleId())) {
- test.setModulePath("/默认模块");
- test.setModuleId("root");
+ if (StringUtils.isEmpty(request.getModulePath()) || StringUtils.isEmpty(request.getModuleId()) || "default-module".equals(request.getModuleId())) {
+ ApiModuleExample example = new ApiModuleExample();
+ example.createCriteria().andProjectIdEqualTo(test.getProjectId()).andProtocolEqualTo(test.getProtocol()).andNameEqualTo("默认模块");
+ List modules = apiModuleMapper.selectByExample(example);
+ if (CollectionUtils.isNotEmpty(modules)) {
+ test.setModuleId(modules.get(0).getId());
+ test.setModulePath("/默认模块");
+ }
}
test.setResponse(JSONObject.toJSONString(request.getResponse()));
test.setEnvironmentId(request.getEnvironmentId());
@@ -604,9 +616,14 @@ public class ApiDefinitionService {
}
for (int i = 0; i < data.size(); i++) {
ApiDefinitionWithBLOBs item = data.get(i);
- if (StringUtils.isEmpty(item.getModuleId())) {
- item.setModuleId("root");
- item.setModulePath("/默认模块");
+ if (StringUtils.isEmpty(item.getModuleId()) || StringUtils.isEmpty(item.getModulePath()) || "default-module".equals(item.getModuleId())) {
+ ApiModuleExample example = new ApiModuleExample();
+ example.createCriteria().andProjectIdEqualTo(item.getProjectId()).andProtocolEqualTo(item.getProtocol()).andNameEqualTo("默认模块");
+ List modules = apiModuleMapper.selectByExample(example);
+ if (CollectionUtils.isNotEmpty(modules)) {
+ item.setModuleId(modules.get(0).getId());
+ item.setModulePath(modules.get(0).getName());
+ }
}
if (item.getName().length() > 255) {
item.setName(item.getName().substring(0, 255));
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java
index a0eddeeca5..b620710743 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiModuleService.java
@@ -39,8 +39,6 @@ public class ApiModuleService extends NodeTreeService {
@Resource
ExtApiModuleMapper extApiModuleMapper;
@Resource
- private ApiDefinitionMapper apiDefinitionMapper;
- @Resource
private ExtApiDefinitionMapper extApiDefinitionMapper;
@Resource
private TestPlanProjectService testPlanProjectService;
@@ -61,6 +59,22 @@ public class ApiModuleService extends NodeTreeService {
}
public List getNodeTreeByProjectId(String projectId, String protocol) {
+ // 判断当前项目下是否有默认模块,没有添加默认模块
+ ApiModuleExample example = new ApiModuleExample();
+ example.createCriteria().andProjectIdEqualTo(projectId).andProtocolEqualTo(protocol).andNameEqualTo("默认模块");
+ long count = apiModuleMapper.countByExample(example);
+ if (count <= 0) {
+ ApiModule record = new ApiModule();
+ record.setId(UUID.randomUUID().toString());
+ record.setName("默认模块");
+ record.setProtocol(protocol);
+ record.setPos(1.0);
+ record.setLevel(1);
+ record.setCreateTime(System.currentTimeMillis());
+ record.setUpdateTime(System.currentTimeMillis());
+ record.setProjectId(projectId);
+ apiModuleMapper.insert(record);
+ }
List apiModules = extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol);
return getNodeTrees(apiModules);
}
diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java
index 23493f60c5..18ad89eed4 100644
--- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java
+++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioModuleService.java
@@ -53,6 +53,22 @@ public class ApiScenarioModuleService extends NodeTreeService getNodeTreeByProjectId(String projectId) {
+ // 判断当前项目下是否有默认模块,没有添加默认模块
+ ApiScenarioModuleExample example = new ApiScenarioModuleExample();
+ example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo("默认模块");
+ long count = apiScenarioModuleMapper.countByExample(example);
+ if (count <= 0) {
+ ApiScenarioModule record = new ApiScenarioModule();
+ record.setId(UUID.randomUUID().toString());
+ record.setName("默认模块");
+ record.setPos(1.0);
+ record.setLevel(1);
+ record.setCreateTime(System.currentTimeMillis());
+ record.setUpdateTime(System.currentTimeMillis());
+ record.setProjectId(projectId);
+ apiScenarioModuleMapper.insert(record);
+ }
+
List nodes = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId);
return getNodeTrees(nodes);
}
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 10eb61872c..f8ab892f8c 100644
--- a/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java
+++ b/backend/src/main/java/io/metersphere/commons/utils/XMLUtils.java
@@ -2,46 +2,140 @@ package io.metersphere.commons.utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
+import io.metersphere.commons.exception.MSException;
+import io.metersphere.i18n.Translator;
import org.apache.commons.lang3.StringUtils;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.regex.*;
public class XMLUtils {
- private static void jsonToXmlStr(JSONObject jObj, StringBuffer buffer) {
+ private static void jsonToXmlStr(JSONObject jObj, StringBuffer buffer, StringBuffer tab) {
Set> se = jObj.entrySet();
+ StringBuffer nowTab = new StringBuffer(tab.toString());
for (Map.Entry en : se) {
if ("com.alibaba.fastjson.JSONObject".equals(en.getValue().getClass().getName())) {
- buffer.append("<").append(en.getKey()).append(">");
+ buffer.append(tab).append("<").append(en.getKey()).append(">\n");
JSONObject jo = jObj.getJSONObject(en.getKey());
- jsonToXmlStr(jo, buffer);
- buffer.append("").append(en.getKey()).append(">");
+ jsonToXmlStr(jo, buffer, nowTab.append("\t"));
+ buffer.append(tab).append("").append(en.getKey()).append(">\n");
} else if ("com.alibaba.fastjson.JSONArray".equals(en.getValue().getClass().getName())) {
JSONArray jarray = jObj.getJSONArray(en.getKey());
for (int i = 0; i < jarray.size(); i++) {
- buffer.append("<").append(en.getKey()).append(">");
+ buffer.append(tab).append("<").append(en.getKey()).append(">\n");
if (StringUtils.isNotBlank(jarray.getString(i))) {
JSONObject jsonobject = jarray.getJSONObject(i);
- jsonToXmlStr(jsonobject, buffer);
- buffer.append("").append(en.getKey()).append(">");
+ jsonToXmlStr(jsonobject, buffer, nowTab.append("\t"));
+ buffer.append(tab).append("").append(en.getKey()).append(">\n");
}
}
} else if ("java.lang.String".equals(en.getValue().getClass().getName())) {
- buffer.append("<").append(en.getKey()).append(">").append(en.getValue());
- buffer.append("").append(en.getKey()).append(">");
+ buffer.append(tab).append("<").append(en.getKey()).append(">").append(en.getValue());
+ buffer.append("").append(en.getKey()).append(">\n");
}
}
}
public static String jsonToXmlStr(JSONObject jObj) {
StringBuffer buffer = new StringBuffer();
- buffer.append("");
+ buffer.append("\n");
try {
- jsonToXmlStr(jObj, buffer);
+ jsonToXmlStr(jObj, buffer, new StringBuffer(""));
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}
return buffer.toString();
}
+
+ // 传入完整的 xml 文本,转换成 json 对象
+ public static JSONObject XmlToJson(String xml) {
+ JSONObject result = new JSONObject();
+ List list = preProcessXml(xml);
+ try {
+ result = (JSONObject) XmlTagToJsonObject(list);
+ } catch (Exception e) {
+ LogUtil.error(e.getMessage(), e);
+ MSException.throwException(Translator.get("illegal_xml_format"));
+ }
+ return result;
+ }
+
+ // 预处理 xml 文本,转换成 tag + data 的列表
+ private static List preProcessXml(String xml) {
+ int begin = xml.indexOf("?>");
+ if(begin != -1) {
+ if(begin + 2 >= xml.length()) {
+ return null;
+ }
+ xml = xml.substring(begin + 2);
+ } // 若存在,则去除
+ String rgex = "\\s*";
+ Pattern pattern = Pattern.compile(rgex);
+ Matcher m = pattern.matcher(xml);
+ xml = m.replaceAll("");
+ rgex = ">";
+ pattern = Pattern.compile(rgex);
+ m = pattern.matcher(xml);
+ xml = m.replaceAll("> ");
+ rgex = "\\s*";
+ pattern = Pattern.compile(rgex);
+ m = pattern.matcher(xml);
+ xml = m.replaceAll(" ");
+ return Arrays.asList(xml.split(" "));
+ }
+
+ // 传入预处理的列表,返回转换成功的 json 对象
+ private static Object XmlTagToJsonObject(List list) {
+ if(list == null || list.size() == 0)
+ return null;
+ Stack tagStack = new Stack<>(); // tag 栈
+ Stack