Jackson?
この組み合わせを使用する場合、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 では問題なく動作しますが、Jackson は次のようにスローします。
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 を使用せず、明示的なカスタム デシリアライザーを使用せずに、Jackson に何らかの方法があるはずです。誰かが解決策を知っていますか?
- 更新、追加情報
Gson は引数コンストラクターをスキップしているように見えるため、リフレクションを使用して舞台裏で引数なしのコンストラクターを作成しているに違いありません。
また、 「-parameters」コンパイラ フラグがなくても、Kotlin データ クラスに対してこれを実行できるKotlin Jackson モジュールが存在します。したがって、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)