jacksonによるJsonシーケンス化と逆シーケンス化
11198 ワード
概要
日常開発ではJSONをデータ転送のフォーマットとして利用することが多く,そのためにJSONシーケンス化(オブジェクトをJSON文字列に変換)や逆シーケンス化(JSON文字列を指定したデータ型に変換)によく用いられる.
本文は主にfasterxmlを利用することを紹介する.jacksonはJSONシーケンス化と逆シーケンス化を実現し,
Unrecognized field
に遭遇した問題について解決する.Gradle依存
fasterxmlを利用する.jacksonはjackson-core,jackson-databindおよびjackson-annotationsに依存しbuild.gradleファイルに依存を追加する例は、次のとおりです.
dependencies {
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.5'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.5'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.5'
}
シーケンス化と逆シーケンス化の実装
JSONツール類
JSONツールクラスを構築し、JSONシーケンス化と逆シーケンス化を実現します.主に使用されるクラスは
com.fasterxml.jackson.databind.ObjectMapper
で、コードの例は以下の通りです.package com.notepad.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
/**
* Created by YM on 2017/6/11.
*/
public class JsonSerializer {
/**
* JSON
*
* @param object
* @return JSON
*/
public static String serialize(Object object) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
return "";
}
}
/**
* JSON
*
* @param jsonStr JSON
* @return a Map
*/
public static Map deserialize(String jsonStr) {
try {
return deserialize(jsonStr, Map.class);
} catch (Exception e) {
e.printStackTrace();
return new HashMap();
}
}
public static T deserialize(String jsonStr, Class classType) throws Exception {
return new ObjectMapper().readValue(jsonStr, classType);
}
}
Entity
作成したJSONツールクラスをテストするために、Entityオブジェクトを定義します.
構築するためのEntityオブジェクトがJSONツールクラスによって操作される場合、Entityについていくつかの説明があります.
package com.notepad.thinkingnote.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Description:
*
* Create: 2018/9/6 22:37
*
* @author Yang Meng
*/
public class Entity {
public Entity() {}
public Entity(String uid, String name) {
this.uid = uid;
this.name = name;
}
/** */
@JsonProperty("UID")
private String uid;
@JsonProperty("name")
private String name;
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
ユニットテスト
ユニットテストを作成し、Entityのシーケンス化と逆シーケンス化をテストします.例は次のとおりです.
package com.notepad.thinkingnote.domain;
import com.notepad.util.JsonSerializer;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Description:
*
* Create: 2018/9/6 22:41
*
* @author Yang Meng
*/
public class EntityTest {
@Test
public void testSerialize() throws Exception {
Entity entity = new Entity("James", "James");
System.out.println(JsonSerializer.serialize(entity));
}
@Test
public void testDeserialize() throws Exception {
String test = "{\"UID\":\"James\",\"name\":\"James\"}";
Entity entity = JsonSerializer.deserialize(test, Entity.class);
System.out.println(entity.getUid() + ":" + entity.getName());
}
}
出力結果は次のとおりです.
// entity , UID
{"UID":"James","name":"James"}
// entity
James:James
UnrecognizedPropertyException
以上の紹介を通して、JSONのシーケンス化と逆シーケンス化を基本的に理解しましたが、時々問題に遭遇することがあります.
このような状況を考慮して,Httpインタフェースから返されるJSON文字列に対して,具体的なEntityオブジェクトを構築したが,Httpインタフェースに突然フィールドtypeが追加され,上記の方法で構築された場合,どのような問題が発生するのか.
単一サンプルをもう1つ作成します.
@Test
public void testDeserialize() throws Exception {
String test = "{\"UID\":\"James\",\"name\":\"James\", \"type\":\"entity\"}";
Entity entity = JsonSerializer.deserialize(test, Entity.class);
System.out.println(entity.getUid() + ":" + entity.getName());
}
UnrecognizedPropertyException異常が発生しました:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" ....
すなわち、新しく追加したtype文字は認識できません.どうやってこの問題を解決しますか?ここでは2つの方法を提供します.
JsonIgnoreProperties注記
fasterxmlを利用する.jacksonが提供する@JsonIgnoreProperties注記は、認識できない属性に対してフィルタリングされます.ここでは主に、逆シーケンス化が必要なオブジェクトEntityを変更します.例を次に示します.
//
@JsonIgnoreProperties(ignoreUnknown = true)
public class Entity {...}
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
メソッド1の修正は,逆シーケンス化が必要なクラスごとに修正する必要があり,不便である.
方法2 JSONツール類の逆シーケンス化方法を修正することにより、DeserializationFeatureを設定する.FAIL_ON_UNKNOWN_PROPERTIESの値はfalseで、1回の修正だけですべてのオブジェクトを適用できます.
例は次のとおりです.
public static T deserialize(String jsonStr, Class classType) throws Exception {
// configure, DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES false
//
return new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(jsonStr, classType);
}
まとめ
本稿では主にjacksonによるJsonシーケンス化と逆シーケンス化を紹介し,UnrecognizedPropertyException異常を解決する2つの方法を示した.