Json 架构和验证的库 Java

Library for Json Schema and Validation in Java

我可以看到有一些库生成 Json 模式和其他可以验证的库。您能否推荐一些可以在 Java 中提供这两种功能的库(带有示例和活动的库)。我正在寻找 Apache 许可库。

我试过Jackson和Gson。
Gson 既不支持 json 模式创建和验证。
Jackson 支持 json 模式生成但不完全支持(例如它不支持 json 模式中的默认值)

此致,

我更喜欢使用 GSON 或 Jackson: - https://www.baeldung.com/jackson-vs-gson

您可以使用 Justify 或 json-schema-validator 参见以下链接: - https://json-schema.org/implementations.html -

希望以上链接能为您提供足够的信息

GSON 和 Jackson 的主要范围是处理 serialization/deserialization 您的数据 to/from JSON。 JSON 模式的生成和验证都不是他们的(主要)关注点。

根据对您的其他问题 (How to display default value in JSON Schema using Jackson) 的评论,模式生成有多种选择——这同样适用于它们的验证。

实现列表(生成和验证)

根据 R.Groote 的回答,您可以在 https://json-schema.org/implementations.html 上找到其中的一些(但不是全部)——包括生成库和验证库。

验证

就我个人而言,到目前为止我只使用过 networknt/json-schema-validator,发现它非常直观且易于使用。它在引擎盖下使用 Jackson,这在我的用例中很实用,因为我已经在使用相同的库进行数据的(反)序列化 from/to JSON – 因此减少了额外的依赖性。


世代

Disclaimer: here comes the biased part as I'm the creator of victools/jsonschema-generator.

JSON 架构生成库的一个示例是 victools/jsonschema-generator。这也在内部使用 Jackson,因此再次与 networknt/json-schema-validator.

类似的依赖关系

jsonschema-generator 库不会填充开箱即用的 "default" 值,但您可以像这样轻松配置它(基于 Jackson @JsonProperty 注释为根据你的其他问题):

SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON);
configBuilder.forFields().withDefaultResolver(field -> {
    JsonProperty annotation = field.getAnnotationConsideringFieldAndGetter(JsonProperty.class);
    return annotation == null || annotation.defaultValue().isEmpty() ? null : annotation.defaultValue());
});
SchemaGenerator generator = new SchemaGenerator(configBuilder.build());
JsonNode jsonSchema = generator.generateSchema(YourClass.class);

System.out.println(jsonSchema.toString());

如果您要满足数字默认值的要求,则可能必须包括 @JsonProperty.defaultValue String 的一些条件解析。

此外,如果您想要对 Jackson 注释进行更具体的处理,您也可以考虑添加可选的 victools/jsonschema-module-jackson


编辑(作为对必须在代码和注释中定义默认值两次的担忧的回应):

使用 victools/jsonschema-generator 您可以完全控制默认值的来源。一种可能的方法是从所遇到的各个对象的实际实例中查找默认值——这里通过您自己的包进行过滤以跳过外部类型。
以下只是可能的粗略示例:

ConcurrentMap<Class<?>, Object> instanceCache = new ConcurrentHashMap<>();
configBuilder.forFields().withDefaultResolver(field -> {
    Class<?> declaringClass = field.getDeclaringType().getErasedType();
    if (!field.isFakeContainerItemScope()
            && declaringClass.getName().startsWith("your.package")) {
        MethodScope getter = field.findGetter();
        if (getter != null) {
            try {
                Object instance = instanceCache.computeIfAbsent(declaringClass, declaringClass::newInstance);
                Object defaultValue = getter.getRawMember().invoke(instance);
                return defaultValue;
            } catch (Exception ex) {
                // most likely missing a no-args constructor
            }
        }
    }
    return null;
});