Можно десериализовать класс с частными полями и настраиваемым конструктором аргументов без использования аннотаций и без изменения класса с помощью Jackson?
Я знаю, что в Джексоне это возможно при использовании этой комбинации: 1) Java 8, 2) компиляция с опцией -parameters и 3) имена параметров соответствуют JSON. Но это также возможно в GSON по умолчанию без всех этих ограничений.
Например:
public class Person {
private final String firstName;
private final String lastName;
private final int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public static void main(String[] args) throws IOException {
String json = "{firstName: \"Foo\", lastName: \"Bar\", age: 30}";
System.out.println("GSON: " + deserializeGson(json)); // works fine
System.out.println("Jackson: " + deserializeJackson(json)); // error
}
public static Person deserializeJackson(String json) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
return mapper.readValue(json, Person.class);
}
public static Person deserializeGson(String json) {
Gson gson = new GsonBuilder().create();
return gson.fromJson(json, Person.class);
}
}
Что отлично работает для GSON, но Джексон бросает:
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `jacksonParametersTest.Person` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{firstName: "Foo", lastName: "Bar", age: 30}"; line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
Это возможно в GSON, поэтому я ожидал, что в Джексоне должен быть какой-то способ без изменения класса Person, без Java 8 и без явного настраиваемого десериализатора. Кто-нибудь знает решение?
- Обновление, дополнительная информация
Кажется, что Gson пропускает конструктор аргументов, поэтому он должен создавать конструктор без аргументов за кулисами, используя отражения.
Кроме того, существует модуль Kotlin Jackson, который может делать это для классов данных Kotlin. , даже без флага компилятора -parameters. Так что странно, что такого решения, похоже, не существует для Java Jackson.
Это (красивое и чистое) решение, доступное в Kotlin Jackson (которое IMO также должно стать доступным в Java Jackson через настраиваемый модуль):
val mapper = ObjectMapper()
.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
.registerModule(KotlinModule())
val person: Person = mapper.readValue(json, Person::class.java)
person
- person Kalaiselvan   schedule 30.11.2017