具有继承和引用的Json Schema Generator

时间:2019-05-16 18:58:59

标签: java json jackson jsonschema

我正在尝试使用具有深继承结构的POJO生成JSON模式。

使用jackson-module-jsonSchema库,我可以生成模式。

给出一个简化的Java示例:

public interface I {...}
public class A implements I {
    public int varA;
}
public class B implements I {
    public int varB;
}
public class C {
    public I varC;
}

下面是我生成架构的代码:

import com.fasterxml.jackson.databind.*
import com.fasterxml.jackson.module.jsonSchema.*

// ...

ObjectMapper mapper = new ObjectMapper();

SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();

mapper.acceptJsonFormatVisitor(mapper.constructType(C.class), visitor);

JsonSchema schema = visitor.finalSchema();

String outputSchemaJson = mapper.writerWithDefaultPrettyPrinter()
                                .writeValueAsString(schema);

实际的Json模式:

{
  "type" : "object",
  "id" : "urn:jsonschema:com:mycompany:GenerateSchemas:C",
  "properties" : {
    "varC" : {
      "type" : "any"
    }
  }
}

所需的Json模式:

{
  "definitions": {
    "A": {
        "type" : "object",
        "id" : "urn:jsonschema:com:mycompany:GenerateSchemas:A",
        "properties" : {
          "varA" : {
            "type" : "integer"
          }
        }
      },
    "B": {
        "type" : "object",
        "id" : "urn:jsonschema:com:mycompany:GenerateSchemas:B",
        "properties" : {
          "varB" : {
            "type" : "integer"
          }
        }
      }
  },
  "type" : "object",
  "id" : "urn:jsonschema:com:mycompany:GenerateSchemas:C",
  "properties" : {
    "varC" : {
      "type" : "object",
      "oneOf": [
        { "$ref": "urn:jsonschema:com:mycompany:GenerateSchemas:A" },
        { "$ref": "urn:jsonschema:com:mycompany:GenerateSchemas:B" }
      ]
    }
  }
}

我尝试从Json Schema库覆盖核心类。 This来自堆栈溢出的答案有助于生成带有引用的架构。

现在,我正在尝试了解我需要重写的内容,以便可以使用反射来获取接口的所有继承类并为其添加oneOf引用。

1 个答案:

答案 0 :(得分:1)

我终于能够弄清楚我需要重写哪些类。

注释

  • Java不支持通过简单的即用型api通过反射来动态查找子类。一种解决方法是使用@JsonSubType注释类,我可以在运行时提取它们。

  • json-module-schema库的2.9.8版本(其中编写了解决方案的修订版1)中,尚不支持对象定义。为了完成工作,我必须重写a few extra classes才能使之成为可能。

  • definitions仅在根级别上在json模式中定义一次,因为可能存在递归引用的情况。


使用更新的POJO代码:

@JsonSubTypes({
    @JsonSubTypes.Type(name = "A", value = A.class),
    @JsonSubTypes.Type(name = "B", value = B.class)
})
public interface I {}

public class A implements I {
    public int varA;
}
public class B implements I {
    public int varB;
}
public class C {
    public I varC;
}

所需的json模式输出已成功生成。

给出以下代码:https://gist.github.com/rrmistry/2246c959d1c9cc45894ecf55305c61fd,我导入了GenerateSchema类以简化模式生成代码:

public void generate() throws Exception {
    generateSchemasFromJavaSubTypes(C.class);
}

private void generateSchemasFromJavaSubTypes(Class<?> classToGenerate) throws Exception {

    JsonSchema schema = GenerateSchemas.generateSchemaFromJavaClass(classToGenerate);

    ObjectMapper mapper = new ObjectMapper();

    String jsonSchemaStr = mapper.writerWithDefaultPrettyPrinter()
                                 .writeValueAsString(schema);
}

已创建GitHub问题以请求本机支持:https://github.com/FasterXML/jackson-module-jsonSchema/issues/135