不明なプロパティを持つJackson Unmarshalling JSON
1. 概要
この記事では、Jackson 2.x、特にhow to deal with JSON content with unknown propertiesでのマーシャリング解除プロセスを見ていきます。
深く掘り下げて、ジャクソンでできる他のクールなことを学びたい場合は、the main Jackson tutorialに進んでください。
2. 追加/不明なフィールドを含むJSONのマーシャリングを解除します
JSON入力はすべての形状とサイズで提供されます。ほとんどの場合、一連のフィールドを持つ事前定義されたJavaオブジェクトにマッピングする必要があります。 目標は、単にignore any JSON properties that cannot be mapped to an existing Java fieldにすることです。
たとえば、JSONを次のJavaエンティティに非整列化する必要があるとします。
public class MyDto {
private String stringValue;
private int intValue;
private boolean booleanValue;
// standard constructor, getters and setters
}
2.1. 不明なフィールドのUnrecognizedPropertyException
プロパティが不明なJSONをこの単純なJavaエンティティにアンマーシャリングしようとすると、com.fasterxml.jackson.databind.exc.UnrecognizedPropertyExceptionになります。
@Test(expected = UnrecognizedPropertyException.class)
public void givenJsonHasUnknownValues_whenDeserializing_thenException()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString =
"{"stringValue":"a"," +
""intValue":1," +
""booleanValue":true," +
""stringValue2":"something"}";
ObjectMapper mapper = new ObjectMapper();
MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);
assertNotNull(readValue);
}
これは次の例外で失敗します。
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "stringValue2" (class org.example.jackson.ignore.MyDto),
not marked as ignorable (3 known properties: "stringValue", "booleanValue", "intValue"])
2.2. ObjectMapperの不明なフィールドの処理
これで、JSONの不明なプロパティを無視するように完全なObjectMapperを構成できます。
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
その後、この種類のJSONを事前定義されたJavaエンティティに読み込むことができます。
@Test
public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknowns_whenDeserializing_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString =
"{"stringValue":"a"," +
""intValue":1," +
""booleanValue":true," +
""stringValue2":"something"}";
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);
assertNotNull(readValue);
assertThat(readValue.getStringValue(), equalTo("a"));
assertThat(readValue.isBooleanValue(), equalTo(true));
assertThat(readValue.getIntValue(), equalTo(1));
}
2.3. クラスの未知のフィールドの処理
ジャクソン全体の代わりにWe can also mark a single class as accepting unknown fieldsObjectMapper:
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDtoIgnoreUnknown { ... }
これで、以前と同じ動作をテストできるはずです。未知のフィールドは単に無視され、既知のフィールドのみがマッピングされます。
@Test
public void givenJsonHasUnknownValuesButIgnoredOnClass_whenDeserializing_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString =
"{"stringValue":"a"," +
""intValue":1," +
""booleanValue":true," +
""stringValue2":"something"}";
ObjectMapper mapper = new ObjectMapper();
MyDtoIgnoreUnknown readValue = mapper
.readValue(jsonAsString, MyDtoIgnoreUnknown.class);
assertNotNull(readValue);
assertThat(readValue.getStringValue(), equalTo("a"));
assertThat(readValue.isBooleanValue(), equalTo(true));
assertThat(readValue.getIntValue(), equalTo(1));
}
3. 不完全なJSONをアンマーシャルする
追加の不明なフィールドと同様に、不完全なJSON(Javaクラスのすべてのフィールドを含まないJSON)のマーシャリングを解除しても、Jacksonでは問題になりません。
@Test
public void givenNotAllFieldsHaveValuesInJson_whenDeserializingAJsonToAClass_thenCorrect()
throws JsonParseException, JsonMappingException, IOException {
String jsonAsString = "{"stringValue":"a","booleanValue":true}";
ObjectMapper mapper = new ObjectMapper();
MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);
assertNotNull(readValue);
assertThat(readValue.getStringValue(), equalTo("a"));
assertThat(readValue.isBooleanValue(), equalTo(true));
}
4. 結論
この記事では、Jacksonを使用して、追加の不明なプロパティでJSONをデシリアライズする方法について説明しました。
これは、APIのエンティティのmap JSON results of external REST APIs to an internal Java representationを必要とすることが多いため、Jacksonを使用するときに構成する最も一般的なものの1つです。
これらすべての例とコードスニペットの実装は、my GitHub projectにあります。