Схема Json с полем anyOf для записи Java

Как я могу генерировать объекты записей Java для схем Java с полем anyOf?

У меня есть следующие схемы:

животные.json

{
    "type": "object",
    "properties": {
        "animals": {
            "type": "array",
            "items": {
                "anyOf": [
                    {"$ref": "mammale.json"},
                    {"$ref": "bird.json"}
                ],
                "minContains": 1,
                "uniqueItems": true
            }
        }
    }
}

млекопитающее.json

{
    "type": "object",
    "properties": {
        "mammalType": {"type": "string"},
        "furColor": {"type": "string"}
    }
}

птица.json

{
    "type": "string"
}

Я хочу вывести json, который выглядит следующим образом:

{
    "animals": [
        {
            "mammalType": "dog",
            "furColour": "brown"
        },
        "someBirdsName"
    ]
}

Есть ли рекомендуемый способ представления структуры anyOf в записях Java (желательно с аннотацией Джексона)?

Я нашел решение при использовании POJO, где они используют интерфейс: Схема Json с полями anyOf для POJO

Это выглядит как хорошее решение, но как мне использовать произвольную строку, которая не реализует интерфейс?

У нас есть 4 генератора для Java, перечисленные на json-schema.org/implementations.html#code-generation. Возможно, один из них подойдет вам.

gregsdennis 30.03.2023 20:48

Я думаю, что интерфейсы — это правильный способ обработки anyOf для строго типизированного языка, такого как .Net или Java. Я думаю, что библиотека делает это правильно.

gregsdennis 30.03.2023 20:49

Является ли цель написать json или прочитать его. Писать легко, потому что Java знает, какие типы записей животных находятся в основном объекте — я могу дать вам ответ, если это так. Чтение, однако, требует, чтобы json животного содержал некоторое указание на тип животного, потому что в противном случае десериализатор не сможет узнать, какой вид животного читается. Если к каждому животному можно добавить AnimalType, то я могу предложить решение.

John Williams 30.03.2023 20:58

Неверно: записи Java действительно могут реализовывать интерфейсы. Запись не может расширять другой класс, потому что она уже расширяет абстрактный класс java.lang.Record. Процитируем JEP 395: Класс записи может реализовывать интерфейсы. Класс записи не может указывать суперкласс, поскольку это означало бы унаследованное состояние, помимо состояния, описанного в заголовке. Однако класс записи может свободно указывать суперинтерфейсы и объявлять методы экземпляра для их реализации. …

Basil Bourque 30.03.2023 22:14

@JohnWilliams цель состоит в том, чтобы сгенерировать json из моей java-записи, я сделал ошибку со слайдом, приведя пример, в реальном мире второй тип anyOf - это просто (массив) строки.

Djoust 31.03.2023 12:28

@BasilBourque Спасибо! Записи могут реализовывать интерфейс. Почему у меня это не сработало, так это то, что запись, которая должна реализовать интерфейс, была вложенной записью. Это легко исправить. Так что я мог бы использовать примеры аннотаций в связанном посте. Но что, если я хочу использовать json opbject и строку в операторе anyOf?

Djoust 31.03.2023 12:29
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для создания json следующим образом:

{
  "animals" : [ {
    "mammalType" : "dog",
    "furColour" : "brown"
  }, 
    "someString"
  ]
}

Что соответствует такой схеме:

{
    "type": "object",
    "properties": {
        "animals": {
            "type": "array",
            "items": {
                "anyOf": [
                    {"$ref": "mammale.json"},
                    {"type": "String"}
                ],
                "minContains": 1,
                "uniqueItems": true
            }
        }
    }
}

Затем это сделает следующее:

public record ResponseServiceAlgolia(Object[] animals) {}

public record Mammal(String mammalType, String furColour) {}

public static void main(String[] args) throws JsonProcessingException {
    
    Mammal mammal = new Mammal("dog", "brown");
    
    Object[] animals = new Object[] {mammal, "someString"};
    ResponseServiceAlgolia responseServiceAlgolia = new ResponseServiceAlgolia(animals);
    
    ObjectMapper objectMapper = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build();
    
    var json = objectMapper.writeValueAsString(responseServiceAlgolia);
    System.out.println(json);

}

Выход:

{
  "animals" : [ {
    "mammalType" : "dog",
    "furColour" : "brown"
  }, "someString" ]
}

Спасибо, это то решение, которое я ищу ... Теперь я вижу, что мне нужно было более четко сформулировать свой первоначальный вопрос и что мне нужно указать желаемый результат в вопросе, я обновлю его. Но в основном вывод, который мне нужно сгенерировать, выглядит так: ``` json { "animals" : [ { "mammalType" : "dog", "furColour" : "brown" }, "someString"] } ``` Надеюсь, вы может помочь мне с этим?

Djoust 31.03.2023 16:46

Хорошо, я идиот, первый пример явно может это сделать...

Djoust 31.03.2023 17:15

В любом случае обновленный ответ

John Williams 31.03.2023 17:25

Другие вопросы по теме