I try to deserialize a huge API payload. This payload contains way more fields than I need and therefore I am utilizing @JsonIgnoreProperties(ignoreUnknown = true). However at some point the deserialization fails with the error message:
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of FIELD_NAME token
at [Source: {
"objectEntries": [
{
"objectKey": "KDS-4300"
},
{
"objectKey": "KDS-4327"
}
]
}; line: 2, column: 3]
I found solutions for that case that suggested the use of
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
I tried this. But it did not help. Also my result data is not a single valued array. It actually contains two values - therefore the solution doesn't add up anyway.
Here are my classes that are the target of the deserialization.
@JsonIgnoreProperties(ignoreUnknown = true)
public class InsightQueryResult {
@JsonProperty("objectEntries")
private List<ObjectEntry> objectEntries;
@JsonCreator
public InsightQueryResult(List<ObjectEntry> objectEntries) {
this.objectEntries = objectEntries;
}
public List<ObjectEntry> getObjectEntries() {
return objectEntries;
}
// equals, hashCode and toString
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class ObjectEntry {
@JsonProperty("objectKey")
private String objectKey;
@JsonCreator
public ObjectEntry(String objectKey) {
this.objectKey = objectKey;
}
public String getObjectKey() {
return objectKey;
}
// equals, hashCode and toString
}
Here is the unit test where I test it out:
@Test
public void shouldMapQueryResultToResultObject() throws IOException {
final Resource expectedQueryResult= new ClassPathResource("testQueryPayload.json");
final String expectedQueryResultData = new String(
Files.readAllBytes(expectedQueryResult.getFile().toPath())).trim();
final List<ObjectEntry> objectEntries = Arrays.asList(new ObjectEntry("KDS-4300"), new ObjectEntry("KD-4327"));
final InsightQueryResult expectedQueryResult = new InsightQueryResult(objectEntries);
final InsightQueryResult result = objectMapper.readValue(expectedQueryResultData, InsightQueryResult.class);
assertThat(result).isEqualTo(expectedQueryResult);
}
And here is the payload I want to deserialize
// testQueryPayload.json
{
"objectEntries": [
{
"objectKey": "KDS-4300"
},
{
"objectKey": "KDS-4327"
}
]
}