验证JSON并提供自定义验证报告

时间:2018-01-14 09:43:35

标签: java json validation

我有一个接收JSON的应用程序,收到它后应验证它。验证包括几个步骤。

  1. 如果收到的对象是格式正确的JSON
  2. 如果存在所有必填字段
  3. 如果满足所有字段约束(即字符串大小)
  4. 如果满足条件依赖关系(如果某个字段的值为A,则另一个字段的值应为B)
  5. 根据描述的要求,如果违反了任何约束,我应该生成我自己的,特别是格式化的验证报告对象

    我已经考虑过如何做到这一点的几种方法,但我对任何一方并不满意,并希望得到你们的建议,如何做到这一点。我考虑过:

    想法#1:Jackson + JSR303 bean验证

    @CustomConstraintIfAThenB // this should emulate the conditional dependency
    public class Message {
        @JsonProperty(value = "a", required = true)
        @Size(min = 3, max = 8)
        private String a;
    
        @JsonProperty(value = "b", required = true)
        @Size(min = 5, max = 9)
        private String b;
    
        // ...
    }
    

    我在这种方法中遇到的问题是在生成报告时,因为首先我需要使用杰克逊的ObjectMapper来尝试创建我的POJO。如果抛出JsonProcessingException我应该解析它,并创建我的报告。如果没有抛出,那么我只能用我的bean验证器验证(即Hibernate)。

    MyReport report = null;
    Message m = null;
    
    // first Jackson validation
    try {
        m = objectMapper.treeToValue(json, Message.class);
    } catch (JsonProcessingException e) {
        report = myExceptionParser.parse(e);
    }
    
    // second bean (field) validation
    Set<ConstraintViolation<Message>> violations = validator.validate(m);
    if (violations.size() > 0) {
        report = myViolationsParser.parse(violations);
    }
    

    这个问题的主要问题是通过JsonProcessingException实际解析来创建我的自定义报告。另外解析violations。我应该编写两个解析器,其中一个(解析异常的解析器)可能会非常笨拙。

    想法#2:针对JSON架构的验证

    我可以编写一个JSON模式,然后根据该模式验证传入的JSON。这方面的好处是我将使用由我正在使用的JSON模式验证器生成的唯一,一致的报告,我应该只为它编写一个解析器。例如,如果我使用fge-validator

    JsonSchema schema = JsonSchemaFactory.byDefault().getJsonSchema(mySchema);
    ProcessingReport report = mySchema.validate(json);
    
    // only have one parser to parse the report to my custom report
    MyReport = myReportParser.parse(report);
    

    问题在于, JSON Schema v4 在处理条件依赖时变得非常笨拙,因为没有IF-THEN-ELSE关键字。我无法找到支持JSON Schema v7的库。此外,修改大型JSON架构可能会变得棘手且非常容易出错。在这种情况下,类注释也会更好。

    有没有第三种方法可以进行JSON验证并从中创建一个自定义报告,这是一种中等优雅,而不是像编写两个解析器(其中一个解析异常)一样笨拙?

    另请注意,我的JSON文件可以轻松拥有200多个字段,因此可能无法逐字段编写自定义反序列化器。

    我想就此提出一些建议,因为我无法找到合理的方法来做到这一点。

0 个答案:

没有答案