ジャクソンのカスタム逆シリアル化入門
1概要
このクイックチュートリアルでは、
2カスタムDeserializer
を使ってJackson 2を使ってJSONをデシリアライズする方法を説明します。
あなたがもっと深く掘り下げて
あなたがジャクソン2
ですることができる** 他のクールなことを学びたいなら –
メインのジャクソンチュートリアル
に向かって進んでください。
2標準の逆シリアル化
2つのエンティティを定義することから始めましょう。そして、カスタマイズなしでJacksonがどのようにこれらのエンティティへのJSON表現を逆シリアル化するのかを見てみましょう。
public class User {
public int id;
public String name;
}
public class Item {
public int id;
public String itemName;
public User owner;
}
それでは、逆シリアル化したいJSON表現を定義しましょう。
{
"id": 1,
"itemName": "theItem",
"owner": {
"id": 2,
"name": "theUser"
}
}
そして最後に、このJSONをJava Entitiesに非整列化しましょう。
Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);
3
ObjectMapper
のカスタムデシリアライザ
前の例では、JSON表現はJavaエンティティと完全に一致しました。次に、JSONを単純化します。
{
"id": 1,
"itemName": "theItem",
"createdBy": 2
}
これをまったく同じエンティティに非整列化する場合 – デフォルトでは、もちろん失敗します。
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "createdBy" (class org.baeldung.jackson.dtos.Item),
not marked as ignorable (3 known properties: "id", "owner", "itemName"])
at[Source:[email protected]; line: 1, column: 43]
(through reference chain: org.baeldung.jackson.dtos.Item["createdBy"])
これを解決するには、カスタムのデシリアライザを使用して** 独自のデシリアライゼーションを実行します。
public class ItemDeserializer extends StdDeserializer<Item> {
public ItemDeserializer() {
this(null);
}
public ItemDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Item deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
int id = (Integer) ((IntNode) node.get("id")).numberValue();
String itemName = node.get("itemName").asText();
int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue();
return new Item(id, itemName, new User(userId, null));
}
}
ご覧のとおり、デシリアライザは標準のJackson表現のJSON(
JsonNode
)を使用しています。入力JSONが
JsonNode
として表されると、それから関連する情報を
抽出して
独自の
Item
エンティティを構築できます。
簡単に言えば、このカスタムのデシリアライザを** 登録して、通常どおりJSONをデシリアライズする必要があります。
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Item.class, new ItemDeserializer());
mapper.registerModule(module);
Item readValue = mapper.readValue(json, Item.class);
4クラスのカスタムデシリアライザ
あるいは、** クラスに直接デシリアライザを登録することもできます。
@JsonDeserialize(using = ItemDeserializer.class)
public class Item {
...
}
デシリアライザをクラスレベルで定義すると、それを
ObjectMapper
に登録する必要はありません。デフォルトのマッパーでうまく動作します。
Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);
このタイプのクラスごとの設定は、設定するために生の
ObjectMapper
に直接アクセスできない可能性がある状況で非常に役立ちます。
5結論
この記事では、Jackson 2を利用して非標準のJSON入力を** 読み取る方法、およびマッピングを完全に制御してその入力を任意のJavaエンティティーグラフにマッピングする方法を説明します。
これらすべての例とコードスニペットの実装は、https://github.com/eugenp/tutorials/tree/master/jackson#readme
にあります。
– これはEclipseベースのプロジェクトです。そのままインポートして実行するのは簡単です。