エラー
Jackson で、ObjectMapper を使用して、以下のように mapper#readValue()
したところ、エラーが発生しました。
-
実装記述
ObjectMapper mapper = new ObjectMapper(); Show show = mapper.readValue(json, Show.class);
-
エラー内容
(through reference chain: xyz.monotalk.social.mixcloud.data.Show["tags"]->java.util.ArrayList[0]->xyz.monotalk.social.mixcloud.data.Tag["type"]) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51) at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:817) at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:980) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1324) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1302) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:249) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:136)
原因と、解決方法
JSON 連想配列にある項目が Java データクラスに定義されていないため、エラーが発生していました。
フィールドを追加して、エラーを解決する
-
修正前のデータクラスの記述
/** * Show * * @author Kem */ @Getter @Setter @AllArgsConstructor @Builder @ToString public class Show extends Response { public Show() { super(); } private String description; }
-
修正後のデータクラスの記述
private String type;
を追加することで、エラーは解消されます。
/** * Show * * @author Kem */ @Getter @Setter @AllArgsConstructor @Builder @ToString public class Show extends Response { public Show() { super(); } private String description; private String type; }
フィールドを無視してエラーにならないようにする
jacksonを使ってjsonをデシリアライズする
に記載がありますが、以下のアノテーションを付与することで、存在しないフィールドを無視することができます。
@JsonIgnoreProperties(ignoreUnknown=true)
JsonAnyGetter で 想定できないフィールドを Map に設定する
以下 が参考になりました。
JacksonHowToIgnoreUnknown · FasterXML/jackson-docs Wiki
jacksonで正体不明のJSONを読み込む - Qiita
JsonAnyGetter
、JsonAnySetter
アノテーションを使って、予期しないフィールドの設定処理、取得処理の実装ができます。
どの方法で解決するか
外部公開サービスの場合、IFの変更のコントロールが難しいので、@JsonIgnoreProperties
を使用するか、JsonAnyGetter
、JsonAnySetter
で拡張属性に設定しておくのが、無難に思いました。
突如追加されるフィールドを登録して使用することはほぼなさそうに思いますので、@JsonIgnoreProperties
で無視しておいて、必要になったら、フィールド定義して明示的に取得するのがよいかと思います。
以上です。
コメント