如何使 json 模式足够灵活以处理枚举的区分大小写的输入?
how to make the json schema flexible enough to handle case sensitive input for enum?
介绍请参考本题。
现在的情况是,如果我通过 userType = CUSTOMER
,那么它不接受请求,在 userType = customer
的情况下也是如此。
任何人都可以向我建议 JSON 架构解决方案吗?
没有一种方法不可怕,但我能想到的最不可怕的事情是使用 pattern
和包含两种情况的正则表达式。
{
"type": "string",
"anyOf": [
{ "title": "Customer", "pattern": "[Cc][Uu][Ss][Tt][Oo][Mm][Ee][Rr]" },
{ "title": "Admin", "pattern": "[Aa][Dd][Mm][Ii][Nn]" },
]
}
(title
不是必需的,对于必须阅读此架构的可怜的开发人员来说,这只是一个很好的选择)
这是我过去几天试图解决的确切用例,有一点很清楚,模式不直接支持它。
现在,如果您使用某种第三方架构验证器工具,他们可能会为您提供一些接口来编写您自己的自定义验证器(https://github.com/everit-org/json-schema)
我们可以做的另一种方法是在验证数据之前预处理数据。假设在您的案例中,userType 是不区分大小写的值,并且仅是一组值(客户、客户、客户)。所以我建议将 enum 值保留为 customer[lowercase] 并且在 JSON 将对其进行模式验证器预处理,以将特定键中的所有值作为小写值。
预处理您的 JSON 的代码可能如下所示 -
CONVERT_TO_LOWER_CASE_KEY_SET - 验证时不区分大小写的键集。
private JsonObject preProcessInputJsonObject(JsonObject inputJsonBody) {
inputJsonBody.forEach(innerObject -> {
if (innerObject.getValue() instanceof String) {
String value = (String) innerObject.getValue();
if (value.trim().isEmpty())
inputJsonBody.putNull(innerObject.getKey());
else if (CONVERT_TO_LOWER_CASE_KEY_SET.contains(innerObject.getKey()))
inputJsonBody.put(innerObject.getKey(), value.trim().toLowerCase());
else
inputJsonBody.put(innerObject.getKey(), value.trim());
}
if (innerObject.getValue() instanceof JsonObject)
inputJsonBody.put(innerObject.getKey(), preProcessInputJsonObject((JsonObject) innerObject.getValue()));
if (innerObject.getValue() instanceof JsonArray)
inputJsonBody.put(innerObject.getKey(), preProcessJsonArray((JsonArray) innerObject.getValue()));
});
return inputJsonBody;
}
private JsonArray preProcessJsonArray(JsonArray inputJsonArray) {
List jsonArrayList = inputJsonArray.copy().getList();
final int size = jsonArrayList.size();
for (int iterator = 0; iterator < size; iterator++) {
if (jsonArrayList.get(iterator) instanceof String) {
String val = (String) jsonArrayList.get(iterator);
if (val.trim().isEmpty())
jsonArrayList.set(iterator, null);
else
jsonArrayList.set(iterator, val.trim());
}
if (jsonArrayList.get(iterator) instanceof JsonObject)
jsonArrayList.set(iterator, preProcessInputJsonObject((JsonObject) jsonArrayList.get(iterator)));
if (jsonArrayList.get(iterator) instanceof JsonArray)
jsonArrayList.set(iterator, preProcessJsonArray((JsonArray) jsonArrayList.get(iterator)));
}
return new JsonArray(jsonArrayList);
}
Note: I also tried removing extra spaces in the string before validating it.
希望对您有所帮助,如果您发现其中有任何疑虑,请告诉我。
One final thing my preprocess data code in java hopefully, you can write something similar in js as well.
介绍请参考本题
现在的情况是,如果我通过 userType = CUSTOMER
,那么它不接受请求,在 userType = customer
的情况下也是如此。
任何人都可以向我建议 JSON 架构解决方案吗?
没有一种方法不可怕,但我能想到的最不可怕的事情是使用 pattern
和包含两种情况的正则表达式。
{
"type": "string",
"anyOf": [
{ "title": "Customer", "pattern": "[Cc][Uu][Ss][Tt][Oo][Mm][Ee][Rr]" },
{ "title": "Admin", "pattern": "[Aa][Dd][Mm][Ii][Nn]" },
]
}
(title
不是必需的,对于必须阅读此架构的可怜的开发人员来说,这只是一个很好的选择)
这是我过去几天试图解决的确切用例,有一点很清楚,模式不直接支持它。
现在,如果您使用某种第三方架构验证器工具,他们可能会为您提供一些接口来编写您自己的自定义验证器(https://github.com/everit-org/json-schema)
我们可以做的另一种方法是在验证数据之前预处理数据。假设在您的案例中,userType 是不区分大小写的值,并且仅是一组值(客户、客户、客户)。所以我建议将 enum 值保留为 customer[lowercase] 并且在 JSON 将对其进行模式验证器预处理,以将特定键中的所有值作为小写值。
预处理您的 JSON 的代码可能如下所示 -
CONVERT_TO_LOWER_CASE_KEY_SET - 验证时不区分大小写的键集。
private JsonObject preProcessInputJsonObject(JsonObject inputJsonBody) {
inputJsonBody.forEach(innerObject -> {
if (innerObject.getValue() instanceof String) {
String value = (String) innerObject.getValue();
if (value.trim().isEmpty())
inputJsonBody.putNull(innerObject.getKey());
else if (CONVERT_TO_LOWER_CASE_KEY_SET.contains(innerObject.getKey()))
inputJsonBody.put(innerObject.getKey(), value.trim().toLowerCase());
else
inputJsonBody.put(innerObject.getKey(), value.trim());
}
if (innerObject.getValue() instanceof JsonObject)
inputJsonBody.put(innerObject.getKey(), preProcessInputJsonObject((JsonObject) innerObject.getValue()));
if (innerObject.getValue() instanceof JsonArray)
inputJsonBody.put(innerObject.getKey(), preProcessJsonArray((JsonArray) innerObject.getValue()));
});
return inputJsonBody;
}
private JsonArray preProcessJsonArray(JsonArray inputJsonArray) {
List jsonArrayList = inputJsonArray.copy().getList();
final int size = jsonArrayList.size();
for (int iterator = 0; iterator < size; iterator++) {
if (jsonArrayList.get(iterator) instanceof String) {
String val = (String) jsonArrayList.get(iterator);
if (val.trim().isEmpty())
jsonArrayList.set(iterator, null);
else
jsonArrayList.set(iterator, val.trim());
}
if (jsonArrayList.get(iterator) instanceof JsonObject)
jsonArrayList.set(iterator, preProcessInputJsonObject((JsonObject) jsonArrayList.get(iterator)));
if (jsonArrayList.get(iterator) instanceof JsonArray)
jsonArrayList.set(iterator, preProcessJsonArray((JsonArray) jsonArrayList.get(iterator)));
}
return new JsonArray(jsonArrayList);
}
Note: I also tried removing extra spaces in the string before validating it.
希望对您有所帮助,如果您发现其中有任何疑虑,请告诉我。
One final thing my preprocess data code in java hopefully, you can write something similar in js as well.