I'm trying to consume a service that gives me an entity with a field that it's an array.
{
"id": "23233",
"items": [
{
"name": "item 1"
},
{
"name": "item 2"
}
]
}
But when the array contains a single item, the item itself is returned, instead of an array of one element.
{
"id": "43567",
"items": {
"name": "item only"
}
}
In this case, Jackson fails to convert to my Java object.
public class ResponseItem {
private String id;
private List<Item> items;
//Getters and setters...
}
Is there an straightforward solution for it?
You are not the first to ask for this problem. It seems pretty old.
After looking at this problem, you can use the DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY
:
Look at the documentation : http://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY
You need to add this jackson feature to your object mapper.
I hope it will help you.
I think the anotation suits the code better.
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Item> items;
A custom JsonDeserializer can be used to solve this.
E.g.
class CustomDeserializer extends JsonDeserializer<List<Item>> {
@Override
public List<Item> deserialize(JsonParser jsonParser, DeserializationContext context)
throws IOException, JsonProcessingException {
JsonNode node = jsonParser.readValueAsTree();
List<Item> items = new ArrayList<>();
ObjectMapper mapper = new ObjectMapper();
if (node.size() == 1) {
Item item = mapper.readValue(node.toString(), Item.class);
items.add(item);
} else {
for (int i = 0; i < node.size(); i++) {
Item item = mapper.readValue(node.get(i).toString(), Item.class);
items.add(item);
}
}
return items;
}
}
you need to tell jackson to use this to de-serialize items
, like:
@JsonDeserialize(using = CustomDeserializer.class)
private List<Item> items;
After that it will work. Happy coding :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With