Json Schema Generator с наследованием и ссылками - PullRequest
2 голосов
/ 16 мая 2019

Я пытаюсь сгенерировать схему JSON, используя POJO с глубокой структурой наследования.

Используя библиотеку 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. Этот ответ от переполнения стека был полезен для создания схемы со ссылками.

Теперь я пытаюсь понять, что мне нужно переопределить, чтобы я мог использовать отражение, чтобы получить все наследующие классы интерфейса и добавить oneOf ссылки на него.

1 Ответ

1 голос
/ 22 мая 2019

Я наконец смог выяснить, какие классы мне нужно переопределить.

Примечания :

  • Java не поддерживает динамическое нахождение подпрограмм-классы через отражение через простой готовый API.Обходным решением было аннотировать классы с помощью @JsonSubType, которые я смог извлечь во время выполнения.

  • В версии 2.9.8 json-module-schema библиотека (где написана ревизия 1 решения), пока нет поддержки определений объектов.Просто чтобы выполнить работу, мне пришлось переопределить несколько дополнительных классов , чтобы сделать это возможным.

  • 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...