Jackson derealization with Spring Boot:获取请求中存在的字段名称以及相应的字段映射
Jackson derealization with SpringBoot : To get field names present in request along with respective field mapping
我需要在不同的情况下抛出不同的错误,像下面这样,而且有很多这样的字段,不仅仅是 1.
例如
-
{
"id": 1,
"name": "nameWithSpecialChar$"
}
这里应该会抛出特殊字符的错误。
-
{
"id": 1,
"name": null
}
此处抛字段空错误
-
{
"id": 1
}
这里抛出字段缺失错误
处理,第一个和第二个场景很简单,但是对于第三个场景,有没有什么方法可以让我们在使用 Jackson 进行序列化时获得输入 json 中传递的字段名称列表?
我能够做到的一种方法是通过将请求映射到 JsonNode,然后检查是否存在所需字段的节点,然后手动反序列化该 JsonNode,然后如下验证其余成员。
public ResponseEntity myGetRequest(@RequestBody JsonNode requestJsonNode) {
if(!requestJsonNode.has("name")){
throw some error;
}
MyRequest request = ObjectMapper.convertValue(requestJsonNode, MyRequest .class);
validateIfFieldsAreInvalid(request);
但是我不喜欢这种方式,请问还有其他方式吗?
您可以定义一个 JSON schema 并根据它验证您的对象。在您的示例中,您的架构可能如下所示:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"description": "The identifier",
"type": "integer"
},
"name": {
"description": "The item name",
"type": "string",
"pattern": "^[a-zA-Z]*$"
}
},
"required": [ "id", "name" ]
}
要验证您的对象,您可以使用 json-schema-validator 库。这个库是建立在 Jackson 之上的。由于您正在使用 Spring Boot,因此您已经导入了 Jackson。
示例代码大致如下所示:
String schema = "<define your schema here>";
String data = "<put your data here>";
JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
ObjectMapper m = new ObjectMapper();
JsonSchema jsonSchema = factory.getJsonSchema(m.readTree(schema));
JsonNode json = m.readTree(data);
ProcessingReport report = jsonSchema.validate(json);
System.out.println(report);
报告包含不同输入案例的详细错误。例如,使用此输入
{
"id": 1,
"name": "nameWithSpecialChar$"
}
此输出被打印出来
--- BEGIN MESSAGES ---
error: ECMA 262 regex "^[a-zA-Z]*$" does not match input string "nameWithSpecialChar$"
level: "error"
schema: {"loadingURI":"#","pointer":"/properties/name"}
instance: {"pointer":"/name"}
domain: "validation"
keyword: "pattern"
regex: "^[a-zA-Z]*$"
string: "nameWithSpecialChar$"
--- END MESSAGES ---
或者不只是打印报告,您可以遍历所有错误并拥有您的特定逻辑
for (ProcessingMessage message : report) {
// Add your logic here
}
您可以查看 example code 以获得有关如何使用该库的更多信息。
我需要在不同的情况下抛出不同的错误,像下面这样,而且有很多这样的字段,不仅仅是 1.
例如
-
{ "id": 1, "name": "nameWithSpecialChar$" }
这里应该会抛出特殊字符的错误。
-
{ "id": 1, "name": null }
此处抛字段空错误
-
{ "id": 1 }
这里抛出字段缺失错误
处理,第一个和第二个场景很简单,但是对于第三个场景,有没有什么方法可以让我们在使用 Jackson 进行序列化时获得输入 json 中传递的字段名称列表?
我能够做到的一种方法是通过将请求映射到 JsonNode,然后检查是否存在所需字段的节点,然后手动反序列化该 JsonNode,然后如下验证其余成员。
public ResponseEntity myGetRequest(@RequestBody JsonNode requestJsonNode) {
if(!requestJsonNode.has("name")){
throw some error;
}
MyRequest request = ObjectMapper.convertValue(requestJsonNode, MyRequest .class);
validateIfFieldsAreInvalid(request);
但是我不喜欢这种方式,请问还有其他方式吗?
您可以定义一个 JSON schema 并根据它验证您的对象。在您的示例中,您的架构可能如下所示:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"description": "The identifier",
"type": "integer"
},
"name": {
"description": "The item name",
"type": "string",
"pattern": "^[a-zA-Z]*$"
}
},
"required": [ "id", "name" ]
}
要验证您的对象,您可以使用 json-schema-validator 库。这个库是建立在 Jackson 之上的。由于您正在使用 Spring Boot,因此您已经导入了 Jackson。
示例代码大致如下所示:
String schema = "<define your schema here>";
String data = "<put your data here>";
JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
ObjectMapper m = new ObjectMapper();
JsonSchema jsonSchema = factory.getJsonSchema(m.readTree(schema));
JsonNode json = m.readTree(data);
ProcessingReport report = jsonSchema.validate(json);
System.out.println(report);
报告包含不同输入案例的详细错误。例如,使用此输入
{
"id": 1,
"name": "nameWithSpecialChar$"
}
此输出被打印出来
--- BEGIN MESSAGES ---
error: ECMA 262 regex "^[a-zA-Z]*$" does not match input string "nameWithSpecialChar$"
level: "error"
schema: {"loadingURI":"#","pointer":"/properties/name"}
instance: {"pointer":"/name"}
domain: "validation"
keyword: "pattern"
regex: "^[a-zA-Z]*$"
string: "nameWithSpecialChar$"
--- END MESSAGES ---
或者不只是打印报告,您可以遍历所有错误并拥有您的特定逻辑
for (ProcessingMessage message : report) {
// Add your logic here
}
您可以查看 example code 以获得有关如何使用该库的更多信息。