Есть ли в Джексоне способ сопоставить позиции массива json с различными свойствами класса?
Например, если у нас есть API, который возвращает свойства человека в виде массива (0 — идентификатор, 1 — имя, 2 — возраст и т. д.), как сопоставить это с объектом, имеющим свойства id, имя и возраст?
"person": [
1,
"Evgeni",
35
]
record Person(Long id, String name, Integer age)
Ищем что-то вроде:
@JsonProperty("<get the item at position 1>") String name




Вы можете создать собственный десериализатор с помощью интерфейса JsonDeserializer и сопоставить содержимое массива JSON с соответствующими свойствами, переопределив класс deserialize(JsonParser p, DeserializationContext ctxt).
Создайте собственный десериализатор:
public class FooBarDeserializer extends JsonDeserializer<FooBar> {
@Override
public FooBar deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
int foo = node.get(0).asInt();
String bar = node.get(1).asText();
return new FooBar(foo, bar);
}
}
Аннотируйте класс с помощью специального десериализатора:
@JsonDeserialize(using = FooBarDeserializer.class)
public class FooBar {
private int foo;
private String bar;
}
Десериализовать JSON:
public static void main(String[] args) throws Exception {
String json = "[42, \"hello\"]";
ObjectMapper mapper = new ObjectMapper();
FooBar fooBar = mapper.readValue(json, FooBar.class);
...
}
Вы можете попробовать использовать библиотеку JSON Josson для преобразования массива JSON в объект.
https://github.com/octomix/josson
ПОЖО Человек
public static class Person {
@JsonProperty("0")
private Long id;
@JsonProperty("1")
private String name;
@JsonProperty("2")
private Integer age;
@Override
public String toString() {
return "Person{" +
"id = " + id +
", name='" + name + '\'' +
", age = " + age +
'}';
}
}
Десериализация, преобразование и преобразование
Josson josson = Josson.fromJsonString("{\"person\":[1,\"Evgeni\",35]}");
JsonNode node = josson.getNode("person.map(#::?).mergeObjects()");
System.out.println("\nJsonNode:\n" + node.toPrettyString());
Person person = Josson.readValueFor(node, Person.class);
System.out.println("\nPerson:\n" + person);
Выражение трансформации:
map() : построить объект.
# обозначают индекс массива, отсчитываемый от нуля.:: извлеките значение поля, чтобы оно стало именем ключа.? обозначает текущее значение узла.mergeObjects(): объединить несколько объектов в один.Выход
JsonNode:
{
"0" : 1,
"1" : "Evgeni",
"2" : 35
}
Person:
Person{id=1, name='Evgeni', age=35}
Спасибо, сделал то же самое с создателем json в конструкторе и вручную сопоставил его внутри.
@JsonCreator public MyObjectToMapTo(List<Object> items) {...}