Jackson による JSON → Java Objectで、JSON 側に対象フィールドキーが存在しない時
エラーにする方法、
@JsonProperty(required=true) を付ければ良いと思っていた。。。
import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class Aelement{ @JsonProperty(required=true) private int length; }
でもこれでは、JSON に "length" が存在しない時にエラーになってくれない。
Jacksonバージョンは、2.12.3 を使用
ObjectMapper の configureメソッドで、
DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES を true でセットしても
期待どおりにならない。
ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, true);
@JsonCreator で、生成されるJavaオブジェクト側内、コンストラクタを用意して
コンストラクタをの引数に、@JsonProperty(required=true) を付けなければ
期待どおりに、必須チェックにならない。
以下のようにする。
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class Aelement{ @JsonCreator public Aelement(@JsonProperty(value="length", required=true)Integer length) { this.length = length; } private int length; }
コンストラクタの引数として @JsonProperty 付与を書くので、value で JSON キーを
書かないとならない。
JSONキーが存在しない時、JsonMappingException で捕捉可能になるわけだが、
実際のExceptionは、MismatchedInputException が発生する。
MismatchedInputException は、JsonMappingException の継承である。
JsonMappingExceptionで捕捉可能である。
ValueInstantiationException も同じである。
よって、以下のように書ける
try{ ObjectMapper mapper = new ObjectMapper(); Aelement a = mapper.readValue(jsontxt, new TypeReference<Aelement>(){}); // TODO }catch(MismatchedInputException e) { System.err.println("catch MismatchedInputException"); System.out.println(e.getMessage()); }catch(ValueInstantiationException e) { System.err.println("catch ValueInstantiationException"); System.out.println(e.getMessage()); }catch (JsonMappingException e){ System.err.println("catch JsonMappingException"); System.out.println(e.getMessage()); }catch (JsonProcessingException e){ System.err.println("catch JsonProcessingException"); System.out.println(e.getMessage()); }
MismatchedInputException は、JsonMappingException の継承
ValueInstantiationException は、JsonMappingException の継承である。
JsonMappingException と、JsonProcessingException だけの
catchブロックでもよいのだが。。
実際の動作は、、、
JSON にキーが存在しない時、
{ }
catch MismatchedInputException Missing required creator property 'length' (index 0) at [Source: (String)"{ }"; line: 3, column: 1] (through reference chain: org.labo.jsons.Aelement["length"])
JSON 値が NULL の時、
{ "length": null }
の時、
catch ValueInstantiationException Cannot construct instance of `org.labo.jsons.Aelement`, problem: `java.lang.NullPointerException` at [Source: (String)"{ "length": null }"; line: 3, column: 1]
JSON 値が 想定外 の時、
{ "length": "" }
catch ValueInstantiationException Cannot construct instance of `org.labo.jsons.Aelement`, problem: `java.lang.NullPointerException` at [Source: (String)"{ "length": "" }"; line: 3, column: 1]
文字列→数値
{ "length": "a" }
catch MismatchedInputException Cannot deserialize value of type `int` from String "a": not a valid `int` value at [Source: (String)"{ "length": "a" }"; line: 2, column: 13] (through reference chain: org.labo.jsons.Aelement["length"])