【Java】JacksonのObjectMapperのreadValueメソッドで例外が発生する。。。対処法は?
JSONからオブジェクトへの変換時にオブジェクトに存在しない項目がJSONデータに含まれていると例外が発生することがあります
5種の対策法をご紹介します!
1. 単純にオブジェクトに対応するフィールドを追加する
JSONデータに存在するがオブジェクトにない項目がある場合、その項目に対応するフィールドをオブジェクトに追加します
この新しいフィールドは変換時には無視されるか、適切なデフォルト値がセットされるようにします
public class MyObject {
private String name;
private int age;
// 新しいフィールド
private String additionalField;
// getterとsetterを追加
public String getAdditionalField() {
return additionalField;
}
public void setAdditionalField(String additionalField) {
this.additionalField = additionalField;
}
// 他のフィールドのgetterとsetterは省略
}
2. オプションを設定して例外を無視する
ObjectMapperの設定を変更して、JSONデータに存在しないフィールドが無視されるようにします
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
MyObject myObject = objectMapper.readValue(jsonString, MyObject.class);
// JSONデータの変換が成功した場合の処理
} catch (IOException e) {
// JSONデータの変換に失敗した場合の処理
}
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) を使うと、未知のプロパティがJSONデータに含まれていても例外が発生せず、変換が成功します
ただし、注意が必要!
この設定は意図しないデータが無視される可能性があります。。。
3. カスタムデシリアライザを実装する
カスタムのJsonDeserializerを実装して、JSONデータをオブジェクトに変換する際に制御を追加します
これにより、不明なプロパティを処理する方法を完全にカスタマイズできます
public class MyObjectDeserializer extends JsonDeserializer<MyObject> {
@Override
public MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectNode node = jsonParser.readValueAsTree();
String name = node.get("name").asText();
int age = node.get("age").asInt();
// 追加のフィールドを取得
String additionalField = null;
if (node.has("additionalField")) {
additionalField = node.get("additionalField").asText();
}
MyObject myObject = new MyObject();
myObject.setName(name);
myObject.setAge(age);
myObject.setAdditionalField(additionalField);
return myObject;
}
}
そして、ObjectMapperでこのカスタムデシリアライザを使用します
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(MyObject.class, new MyObjectDeserializer());
objectMapper.registerModule(module);
MyObject myObject = objectMapper.readValue(jsonString, MyObject.class);
ぜひお試しください!
4. @JsonIgnorePropertiesアノテーションを使用する
クラスレベルで@JsonIgnorePropertiesアノテーションを使用して、不明なプロパティを無視するように指定できます
このアノテーションをクラスに付けることで、JSONに存在するがクラスに定義されていないプロパティを無視します
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyObject {
private String name;
private int age;
// getterとsetterを追加
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
5. JsonNodeを使って柔軟に処理する
一度、JsonNodeにパースしてから必要なフィールドを抽出する方法です
柔軟にデータを扱うことができます
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode rootNode = objectMapper.readTree(jsonString);
String name = rootNode.path("name").asText();
int age = rootNode.path("age").asInt();
MyObject myObject = new MyObject();
myObject.setName(name);
myObject.setAge(age);
// JSONデータの変換が成功した場合の処理
} catch (IOException e) {
// JSONデータの変換に失敗した場合の処理
}
是非フォローしてください
最新の情報をお伝えします