Как я могу генерировать объекты записей 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
Это выглядит как хорошее решение, но как мне использовать произвольную строку, которая не реализует интерфейс?
Я думаю, что интерфейсы — это правильный способ обработки anyOf для строго типизированного языка, такого как .Net или Java. Я думаю, что библиотека делает это правильно.
Является ли цель написать json или прочитать его. Писать легко, потому что Java знает, какие типы записей животных находятся в основном объекте — я могу дать вам ответ, если это так. Чтение, однако, требует, чтобы json животного содержал некоторое указание на тип животного, потому что в противном случае десериализатор не сможет узнать, какой вид животного читается. Если к каждому животному можно добавить AnimalType, то я могу предложить решение.
Неверно: записи Java действительно могут реализовывать интерфейсы. Запись не может расширять другой класс, потому что она уже расширяет абстрактный класс java.lang.Record. Процитируем JEP 395: Класс записи может реализовывать интерфейсы. Класс записи не может указывать суперкласс, поскольку это означало бы унаследованное состояние, помимо состояния, описанного в заголовке. Однако класс записи может свободно указывать суперинтерфейсы и объявлять методы экземпляра для их реализации. …
@JohnWilliams цель состоит в том, чтобы сгенерировать json из моей java-записи, я сделал ошибку со слайдом, приведя пример, в реальном мире второй тип anyOf - это просто (массив) строки.
@BasilBourque Спасибо! Записи могут реализовывать интерфейс. Почему у меня это не сработало, так это то, что запись, которая должна реализовать интерфейс, была вложенной записью. Это легко исправить. Так что я мог бы использовать примеры аннотаций в связанном посте. Но что, если я хочу использовать json opbject и строку в операторе anyOf?




Для создания 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"] } ``` Надеюсь, вы может помочь мне с этим?
Хорошо, я идиот, первый пример явно может это сделать...
В любом случае обновленный ответ
У нас есть 4 генератора для Java, перечисленные на json-schema.org/implementations.html#code-generation. Возможно, один из них подойдет вам.