fix(接口测试): 修复JSON-Schema请求参数对数字类型使用变量变成字符问题
--bug=1019328 --user=赵勇 [接口测试]github#19415用场景变量和前置返回的变量 int类型的值 都会转成string,也设置成 number 和 integer 都不行 https://www.tapd.cn/55049933/s/1345270
This commit is contained in:
parent
8000f871d3
commit
c52040dcc0
|
@ -62,14 +62,6 @@ public class Body {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isOldKV() {
|
||||
if (StringUtils.equals(type, KV)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public List<KeyValue> getBodyParams(HTTPSamplerProxy sampler, String requestId) {
|
||||
List<KeyValue> body = new ArrayList<>();
|
||||
if (this.isKV() || this.isBinary()) {
|
||||
|
@ -84,7 +76,7 @@ public class Body {
|
|||
}
|
||||
} else {
|
||||
if (StringUtils.isNotEmpty(this.getRaw()) || this.getJsonSchema() != null) {
|
||||
parseJonBodyMock();
|
||||
analyticalData();
|
||||
KeyValue keyValue = new KeyValue(StringUtils.EMPTY, JSON_SCHEMA, this.getRaw(), true, true);
|
||||
sampler.setPostBodyRaw(true);
|
||||
keyValue.setEnable(true);
|
||||
|
@ -95,33 +87,43 @@ public class Body {
|
|||
return body;
|
||||
}
|
||||
|
||||
private void parseJonBodyMock() {
|
||||
if (StringUtils.isNotBlank(this.type) && StringUtils.equals(this.type, JSON_STR)) {
|
||||
if (StringUtils.isNotEmpty(this.format) && this.getJsonSchema() != null
|
||||
&& JSON_SCHEMA.equals(this.format)) {
|
||||
this.raw = StringEscapeUtils.unescapeJava(JSONSchemaBuilder.generator(JSONUtil.toJSONString(this.getJsonSchema())));
|
||||
private void parseMock() {
|
||||
if (StringUtils.isNotEmpty(this.getRaw())) {
|
||||
String value = StringUtils.chomp(this.getRaw().trim());
|
||||
if (StringUtils.startsWith(value, "[") && StringUtils.endsWith(value, "]")) {
|
||||
List list = JSON.parseArray(this.getRaw());
|
||||
if (!this.getRaw().contains(ElementConstants.REF)) {
|
||||
jsonMockParse(list);
|
||||
}
|
||||
this.raw = JSONUtil.toJSONString(list);
|
||||
} else {
|
||||
try {
|
||||
if (StringUtils.isNotEmpty(this.getRaw())) {
|
||||
String value = StringUtils.chomp(this.getRaw().trim());
|
||||
if (StringUtils.startsWith(value, "[") && StringUtils.endsWith(value, "]")) {
|
||||
List list = JSON.parseArray(this.getRaw());
|
||||
if (!this.getRaw().contains("$ref")) {
|
||||
jsonMockParse(list);
|
||||
}
|
||||
this.raw = JSONUtil.parserArray(JSONUtil.toJSONString(list));
|
||||
} else {
|
||||
Map<String, Object> map = JSON.parseObject(this.getRaw(), Map.class);
|
||||
if (!this.getRaw().contains("$ref")) {
|
||||
jsonMockParse(map);
|
||||
}
|
||||
this.raw = JSONUtil.parserObject(JSONUtil.toJSONString(map));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("json mock value is abnormal", e);
|
||||
Map<String, Object> map = JSON.parseObject(this.getRaw(), Map.class);
|
||||
if (!this.getRaw().contains(ElementConstants.REF)) {
|
||||
jsonMockParse(map);
|
||||
}
|
||||
this.raw = JSONUtil.toJSONString(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void analyticalData() {
|
||||
try {
|
||||
boolean isArray = false;
|
||||
if (StringUtils.isNotBlank(this.type) && StringUtils.equals(this.type, JSON_STR)) {
|
||||
if (StringUtils.isNotEmpty(this.format) && this.getJsonSchema() != null && JSON_SCHEMA.equals(this.format)) {
|
||||
this.raw = StringEscapeUtils.unescapeJava(JSONSchemaBuilder.generator(JSONUtil.toJSONString(this.getJsonSchema())));
|
||||
} else {
|
||||
parseMock();
|
||||
}
|
||||
// 格式化处理
|
||||
if (isArray) {
|
||||
this.raw = JSONUtil.parserArray(this.raw);
|
||||
} else {
|
||||
this.raw = JSONUtil.parserObject(this.raw);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LoggerUtil.error("json mock value is abnormal", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class JSONSchemaBuilder {
|
|||
return "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value);
|
||||
}
|
||||
|
||||
private static void valueOf(String evlValue, String propertyName, JSONObject concept) {
|
||||
private static boolean valueOf(String evlValue, String propertyName, JSONObject concept) {
|
||||
if (StringUtils.startsWith(evlValue, "@")) {
|
||||
String str = ScriptEngineUtils.calculate(evlValue);
|
||||
switch (evlValue) {
|
||||
|
@ -73,8 +73,10 @@ public class JSONSchemaBuilder {
|
|||
concept.put(propertyName, str);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
concept.put(propertyName, ScriptEngineUtils.buildFunctionCallString(evlValue));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +124,11 @@ public class JSONSchemaBuilder {
|
|||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
valueOf(FormatterUtil.getElementValue(object).getAsString(), propertyName, concept);
|
||||
boolean hasValue = valueOf(FormatterUtil.getElementValue(object).getAsString(), propertyName, concept);
|
||||
if (hasValue) {
|
||||
String value = FormatterUtil.getElementValue(object).getAsString();
|
||||
processValue(concept, map, propertyName, value);
|
||||
}
|
||||
}
|
||||
} else if (propertyObjType.equals(PropertyConstant.BOOLEAN)) {
|
||||
// 先设置空值
|
||||
|
@ -137,10 +143,7 @@ public class JSONSchemaBuilder {
|
|||
if (isBoolean(value)) {
|
||||
concept.put(propertyName, Boolean.valueOf(value));
|
||||
} else {
|
||||
concept.put(propertyName, value);
|
||||
String key = StringUtils.join("\"", propertyName, "\"", ": \"", value, "\"");
|
||||
String targetValue = StringUtils.join("\"", propertyName, "\"", ":", value);
|
||||
map.put(key, targetValue);
|
||||
processValue(concept, map, propertyName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,6 +161,19 @@ public class JSONSchemaBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
public static void processValue(JSONObject concept, Map<String, String> map, String propertyName, String value) {
|
||||
concept.put(propertyName, value);
|
||||
String key = StringUtils.join("\"", propertyName, "\"", ":\"", value, "\"");
|
||||
String targetValue = StringUtils.join("\"", propertyName, "\"", ":", value);
|
||||
map.put(key, targetValue);
|
||||
}
|
||||
|
||||
public static void processArrayValue(Map<String, String> map, String value) {
|
||||
String key = StringUtils.join("\"",value, "\"");
|
||||
String targetValue = StringUtils.join(value);
|
||||
map.put(key, targetValue);
|
||||
}
|
||||
|
||||
private static void analyzeArray(JSONObject concept, String propertyName, JsonObject object, Map<String, String> map) {
|
||||
JSONArray array = new JSONArray();
|
||||
if (object.has(PropertyConstant.ITEMS)) {
|
||||
|
@ -176,7 +192,7 @@ public class JSONSchemaBuilder {
|
|||
JsonObject itemsObject = element.getAsJsonObject();
|
||||
if (object.has(PropertyConstant.ITEMS)) {
|
||||
if (FormatterUtil.isMockValue(itemsObject)) {
|
||||
formatItems(itemsObject, targetArray);
|
||||
formatItems(itemsObject, targetArray, map);
|
||||
} else if (itemsObject.has(PropertyConstant.TYPE) && (itemsObject.has(PropertyConstant.ENUM) || itemsObject.get(PropertyConstant.TYPE).getAsString().equals(PropertyConstant.STRING))) {
|
||||
targetArray.put(FormatterUtil.getMockValue(itemsObject));
|
||||
} else if (itemsObject.has(PropertyConstant.TYPE) && itemsObject.get(PropertyConstant.TYPE).getAsString().equals(PropertyConstant.NUMBER)) {
|
||||
|
@ -202,12 +218,12 @@ public class JSONSchemaBuilder {
|
|||
});
|
||||
}
|
||||
|
||||
private static void formatItems(JsonObject itemsObject, JSONArray array) {
|
||||
private static void formatItems(JsonObject itemsObject, JSONArray array, Map<String, String> map) {
|
||||
String type = StringUtils.EMPTY;
|
||||
if (itemsObject.has(PropertyConstant.TYPE)) {
|
||||
type = itemsObject.get(PropertyConstant.TYPE).getAsString();
|
||||
}
|
||||
try {
|
||||
String type = StringUtils.EMPTY;
|
||||
if (itemsObject.has(PropertyConstant.TYPE)) {
|
||||
type = itemsObject.get(PropertyConstant.TYPE).getAsString();
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(type, PropertyConstant.STRING)) {
|
||||
String value = FormatterUtil.getStrValue(itemsObject);
|
||||
array.put(value);
|
||||
|
@ -227,6 +243,10 @@ public class JSONSchemaBuilder {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
arrayValueOf(FormatterUtil.getStrValue(itemsObject), array);
|
||||
if (StringUtils.equalsAnyIgnoreCase(type, PropertyConstant.INTEGER, PropertyConstant.NUMBER)) {
|
||||
String value = FormatterUtil.getElementValue(itemsObject).getAsString();
|
||||
processArrayValue(map, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,32 +5,35 @@ import io.metersphere.commons.constants.PropertyConstant;
|
|||
import io.metersphere.commons.utils.EnumPropertyUtil;
|
||||
import io.metersphere.commons.utils.JSONUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class JSONSchemaParser {
|
||||
|
||||
private static void analyzeSchema(String json, JSONObject rootObj) {
|
||||
private static void analyzeSchema(String json, JSONObject rootObj, Map<String, String> processMap) {
|
||||
Gson gson = new Gson();
|
||||
JsonElement element = gson.fromJson(json, JsonElement.class);
|
||||
JsonObject rootElement = element.getAsJsonObject();
|
||||
analyzeRootSchemaElement(rootElement, rootObj);
|
||||
analyzeRootSchemaElement(rootElement, rootObj, processMap);
|
||||
}
|
||||
|
||||
private static void analyzeRootSchemaElement(JsonObject rootElement, JSONObject rootObj) {
|
||||
private static void analyzeRootSchemaElement(JsonObject rootElement, JSONObject rootObj, Map<String, String> processMap) {
|
||||
if (rootElement.has(PropertyConstant.TYPE) || rootElement.has(PropertyConstant.ALL_OF)) {
|
||||
analyzeObject(rootElement, rootObj);
|
||||
analyzeObject(rootElement, rootObj, processMap);
|
||||
}
|
||||
if (rootElement.has("definitions")) {
|
||||
analyzeDefinitions(rootElement);
|
||||
analyzeDefinitions(rootElement, processMap);
|
||||
}
|
||||
}
|
||||
|
||||
private static void analyzeObject(JsonObject object, JSONObject rootObj) {
|
||||
private static void analyzeObject(JsonObject object, JSONObject rootObj, Map<String, String> processMap) {
|
||||
if (object != null && object.has(PropertyConstant.ALL_OF)) {
|
||||
JsonArray allOfArray = object.get(PropertyConstant.ALL_OF).getAsJsonArray();
|
||||
for (JsonElement allOfElement : allOfArray) {
|
||||
|
@ -38,29 +41,32 @@ public class JSONSchemaParser {
|
|||
if (!allOfElementObj.has(PropertyConstant.PROPERTIES)) {
|
||||
continue;
|
||||
}
|
||||
formatObject(allOfElementObj, rootObj);
|
||||
formatObject(allOfElementObj, rootObj, processMap);
|
||||
}
|
||||
} else if (object.has(PropertyConstant.PROPERTIES)) {
|
||||
formatObject(object, rootObj);
|
||||
formatObject(object, rootObj, processMap);
|
||||
} else if (object.has(PropertyConstant.ADDITIONAL_PROPERTIES)) {
|
||||
analyzeProperty(rootObj, PropertyConstant.ADDITIONAL_PROPERTIES, object.get(PropertyConstant.ADDITIONAL_PROPERTIES).getAsJsonObject());
|
||||
} else if (object.has(PropertyConstant.TYPE) && object.get(PropertyConstant.TYPE).getAsString().equals(PropertyConstant.ARRAY)) {
|
||||
analyzeProperty(rootObj, PropertyConstant.MS_OBJECT, object);
|
||||
} else if (object.has(PropertyConstant.TYPE) && !object.get(PropertyConstant.TYPE).getAsString().equals(PropertyConstant.OBJECT)) {
|
||||
analyzeProperty(rootObj, object.getAsString(), object);
|
||||
analyzeProperty(rootObj, PropertyConstant.ADDITIONAL_PROPERTIES,
|
||||
object.get(PropertyConstant.ADDITIONAL_PROPERTIES).getAsJsonObject(), processMap);
|
||||
} else if (object.has(PropertyConstant.TYPE)
|
||||
&& object.get(PropertyConstant.TYPE).getAsString().equals(PropertyConstant.ARRAY)) {
|
||||
analyzeProperty(rootObj, PropertyConstant.MS_OBJECT, object, processMap);
|
||||
} else if (object.has(PropertyConstant.TYPE)
|
||||
&& !object.get(PropertyConstant.TYPE).getAsString().equals(PropertyConstant.OBJECT)) {
|
||||
analyzeProperty(rootObj, object.getAsString(), object, processMap);
|
||||
}
|
||||
}
|
||||
|
||||
private static void formatObject(JsonObject object, JSONObject rootObj) {
|
||||
private static void formatObject(JsonObject object, JSONObject rootObj, Map<String, String> processMap) {
|
||||
JsonObject propertiesObj = object.get(PropertyConstant.PROPERTIES).getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry : propertiesObj.entrySet()) {
|
||||
String propertyKey = entry.getKey();
|
||||
JsonObject propertyObj = propertiesObj.get(propertyKey).getAsJsonObject();
|
||||
analyzeProperty(rootObj, propertyKey, propertyObj);
|
||||
analyzeProperty(rootObj, propertyKey, propertyObj, processMap);
|
||||
}
|
||||
}
|
||||
|
||||
private static void analyzeProperty(JSONObject concept, String propertyName, JsonObject object) {
|
||||
private static void analyzeProperty(JSONObject concept, String propertyName, JsonObject object, Map<String, String> processMap) {
|
||||
if (!object.has(PropertyConstant.TYPE)) {
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +111,7 @@ public class JSONSchemaParser {
|
|||
concept.put(propertyName, value);
|
||||
} else {
|
||||
String value = FormatterUtil.getStrValue(object);
|
||||
concept.put(propertyName, value);
|
||||
JSONSchemaBuilder.processValue(concept, processMap, propertyName, value);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(type, PropertyConstant.NUMBER)) {
|
||||
|
@ -123,7 +129,7 @@ public class JSONSchemaParser {
|
|||
concept.put(propertyName, value.floatValue());
|
||||
}
|
||||
} else {
|
||||
concept.put(propertyName, FormatterUtil.getStrValue(object));
|
||||
JSONSchemaBuilder.processValue(concept, processMap, propertyName, FormatterUtil.getStrValue(object));
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.equals(type, PropertyConstant.BOOLEAN)) {
|
||||
|
@ -142,11 +148,11 @@ public class JSONSchemaParser {
|
|||
}
|
||||
}
|
||||
} else if (StringUtils.equals(type, PropertyConstant.ARRAY)) {
|
||||
analyzeArray(concept, propertyName, object);
|
||||
analyzeArray(concept, propertyName, object, processMap);
|
||||
} else if (StringUtils.equals(type, PropertyConstant.OBJECT)) {
|
||||
JSONObject obj = JSONUtil.createJsonObject(true);
|
||||
concept.put(propertyName, obj);
|
||||
analyzeObject(object, obj);
|
||||
analyzeObject(object, obj, processMap);
|
||||
} else if (StringUtils.equalsIgnoreCase(type, "null")) {
|
||||
concept.put(propertyName, JSONObject.NULL);
|
||||
} else {
|
||||
|
@ -154,12 +160,12 @@ public class JSONSchemaParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static void analyzeArray(JSONObject concept, String propertyName, JsonObject object) {
|
||||
private static void analyzeArray(JSONObject concept, String propertyName, JsonObject object, Map<String, String> processMap) {
|
||||
JSONArray array = new JSONArray();
|
||||
if (object.has(PropertyConstant.ITEMS)) {
|
||||
if (object.get(PropertyConstant.ITEMS).isJsonArray()) {
|
||||
JsonArray jsonArray = object.get(PropertyConstant.ITEMS).getAsJsonArray();
|
||||
loopArray(array, jsonArray, object, propertyName);
|
||||
loopArray(array, jsonArray, object, propertyName, processMap);
|
||||
} else {
|
||||
JsonObject itemsObject = object.get(PropertyConstant.ITEMS).getAsJsonObject();
|
||||
array.put(itemsObject);
|
||||
|
@ -168,7 +174,7 @@ public class JSONSchemaParser {
|
|||
concept.put(propertyName, array);
|
||||
}
|
||||
|
||||
private static void loopArray(JSONArray array, JsonArray jsonArray, JsonObject object, String propertyName) {
|
||||
private static void loopArray(JSONArray array, JsonArray jsonArray, JsonObject object, String propertyName, Map<String, String> processMap) {
|
||||
jsonArray.forEach(element -> {
|
||||
JsonObject jsonObject = element.getAsJsonObject();
|
||||
if (object.has(PropertyConstant.ITEMS)) {
|
||||
|
@ -200,12 +206,12 @@ public class JSONSchemaParser {
|
|||
}
|
||||
} else if (jsonObject.has(PropertyConstant.PROPERTIES)) {
|
||||
JSONObject propertyConcept = JSONUtil.createJsonObject(true);
|
||||
formatObject(jsonObject, propertyConcept);
|
||||
formatObject(jsonObject, propertyConcept, processMap);
|
||||
array.put(propertyConcept);
|
||||
|
||||
} else if (jsonObject.has(PropertyConstant.TYPE) && jsonObject.get(PropertyConstant.TYPE) instanceof JsonPrimitive) {
|
||||
JSONObject newJsonObj = JSONUtil.createJsonObject(true);
|
||||
analyzeProperty(newJsonObj, propertyName + PropertyConstant.ITEM, jsonObject);
|
||||
analyzeProperty(newJsonObj, propertyName + PropertyConstant.ITEM, jsonObject, processMap);
|
||||
array.put(newJsonObj.get(propertyName + PropertyConstant.ITEM));
|
||||
}
|
||||
} else if (object.has(PropertyConstant.ITEMS) && object.get(PropertyConstant.ITEMS).isJsonArray()) {
|
||||
|
@ -215,24 +221,33 @@ public class JSONSchemaParser {
|
|||
});
|
||||
}
|
||||
|
||||
private static void analyzeDefinitions(JsonObject object) {
|
||||
private static void analyzeDefinitions(JsonObject object, Map<String, String> processMap) {
|
||||
JsonObject definitionsObj = object.get("definitions").getAsJsonObject();
|
||||
for (Entry<String, JsonElement> entry : definitionsObj.entrySet()) {
|
||||
String definitionKey = entry.getKey();
|
||||
JsonObject definitionObj = definitionsObj.get(definitionKey).getAsJsonObject();
|
||||
JSONObject obj = JSONUtil.createJsonObject(true);
|
||||
analyzeRootSchemaElement(definitionObj, obj);
|
||||
analyzeRootSchemaElement(definitionObj, obj, processMap);
|
||||
}
|
||||
}
|
||||
|
||||
private static String formerJson(String jsonSchema) {
|
||||
JSONObject root = JSONUtil.createJsonObject(true);
|
||||
analyzeSchema(jsonSchema, root);
|
||||
Map<String, String> processMap = new HashMap<>();
|
||||
String json;
|
||||
analyzeSchema(jsonSchema, root, processMap);
|
||||
// 格式化返回
|
||||
if (root.opt(PropertyConstant.MS_OBJECT) != null) {
|
||||
return root.get(PropertyConstant.MS_OBJECT).toString();
|
||||
json = root.get(PropertyConstant.MS_OBJECT).toString();
|
||||
} else {
|
||||
json = root.toString();
|
||||
}
|
||||
return root.toString();
|
||||
if (MapUtils.isNotEmpty(processMap)) {
|
||||
for (String str : processMap.keySet()) {
|
||||
json = json.replace(str, processMap.get(str));
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static String schemaToJson(String jsonSchema) {
|
||||
|
|
|
@ -61,5 +61,5 @@ public class ElementConstants {
|
|||
public static final String MS_KEYSTORE_FILE_PATH = "MS-KEYSTORE-FILE-PATH";
|
||||
public static final String MS_KEYSTORE_FILE_PASSWORD = "MS-KEYSTORE-FILE-PASSWORD";
|
||||
public static final String VIRTUAL_STEPS = "VIRTUAL_STEPS";
|
||||
|
||||
public static final String REF = "$ref";
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ public class JSONUtil {
|
|||
.disableHtmlEscaping()
|
||||
.serializeNulls()
|
||||
.create();
|
||||
;
|
||||
|
||||
static {
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
|
Loading…
Reference in New Issue