As input for my Application I might get either a single JsonObject, or a List of them:
input1 = [ { "prop": "val1" }, { "prop": "val2" } ]
input2 = { "prop": "val" }
I can use JsonNode
as target type for both inputs
objectMapper.readValue(input1, JsonNode.class);
objectMapper.readValue(input2, JsonNode.class);
And then evaluate whether the root node is a ArrayNode
or ObjectNode
.
I seek a way to define my custom target type, like a List<MyObject>
which has one Element if a JsonObject is provided, or zero to multiple, if a List is provided.
objectMapper.readValue(input, new TypeRef<ArrayList<MyObject>>() {});
however fails for the single object - it can not construc an Array-Type from {.
I was trying to create my own type:
public class MyList extends ArrayList<MyObject> {
public String prop;
@JsonCreator
public MyList(String prop) {
super();
this.prop = prop; // Resp add(new MyObject(prop));
}
public MyList() {}
}
But Jackson refuses to use the JsonCreator for single objects.
Is there any way, I could do that (ideally without a custom serializer, unless that one can be made pretty generic)
Of course, Jackson has an easy solution for that:
DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY
to your help!
@EqualsAndHashCode
public class Example {
@JsonProperty public String name
}
@Test
public void experiment() {
ObjectMapper om = new ObjectMapper();
om.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
String list= "[{ \"name\": \"peter\" }]";
String single= "{ \"name\": \"peter\" }";
List<Example> respList = om.readValue(list, new TypeReference<List<Example>>() {});
List<Example> respSingle = om.readValue(single, new TypeReference<List<Example>>() {});
Assert.assertEquals(respList, respSingle)
}