Мне трудно понять, как работает аннотация Джексона @JsonCreator
(особенно с различными режимами).
Я пытался максимально упростить:
public class JacksonDeserialization {
private ObjectMapper om = new ObjectMapper();
@Test // 1
public void test_deserialization_emptyJson() throws JsonParseException, JsonMappingException, IOException {
Wrapper read = om.readValue("{}", Wrapper.class);
// Throws here: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `Inner` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
assertThat(read).isNotNull();
assertThat(read.getInner()).isNull();
}
@Test // 2
public void test_deserialization_innerIsEmpty() throws JsonParseException, JsonMappingException, IOException {
Wrapper read = om.readValue("{\"inner\":{}}", Wrapper.class);
// Throws here: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "inner" (class Inner), not marked as ignorable (one known property: "prop"])
assertThat(read).isNotNull();
assertThat(read.getInner()).isNotNull();
}
@Test // 3
public void test_deserialization_innerIsSet() throws JsonParseException, JsonMappingException, IOException {
Wrapper read = om.readValue("{\"inner\":{\"prop\":\"42\"}}", Wrapper.class);
// Throws here: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "inner" (class Inner), not marked as ignorable (one known property: "prop"])
assertThat(read).isNotNull();
assertThat(read.getInner()).isNotNull();
assertThat(read.getInner().getProp()).isEqualTo("42");
}
}
Мой классы объектов:
public class Wrapper {
private Inner inner;
@JsonCreator
public Wrapper(Inner inner) {
this.inner = inner;
}
public Inner getInner() {
return inner;
}
}
и
public class Inner {
private String prop;
@JsonCreator
public Inner(String prop) {
this.prop = prop;
}
public String getProp() {
return prop;
}
}
Выдержки из @JsonCreator
Javado c:
ПРИМЕЧАНИЕ: при аннотировании методов-создателей (конструкторов) , фабричные методы), метод должен быть либо:
• Метод конструктора / фабрики с одним аргументом без JsonPropertyannotation для аргумента: если это так, это так называемый «создатель делегата», в этом случае Джексон сначала связывается JSON в тип аргумента, а затем вызывает создателя. Это часто используется вместе с JsonValue (используется для сериализации).
... и из аргумента mode
:
Значение по умолчанию для Mode.DEFAULT означает, что вызывающая сторона должна использовать стандартную эвристику для выбора используемого режима.
com.fasterxml.jackson.annotation.JsonCreator.Mode.DEFAULT
Javado c:
Псевдо-режим, который указывает, что вызывающий абонент должен использовать эвристику по умолчанию для выбора используемого режима. Это обычно способствует использованию режима делегирования для создателей с одним аргументом, которые принимают структурированные типы.
Что я сделал не так в этих объяснениях?
Я использую Jackson 2.9.9.20190807, как указано 1 pom. xml от Spring Boot, который мы используем.