I’ve been trying to deserialize an array of JSON objects for a while now, and all the answers on the internet are either deprecated or just don’t work for me.
The code below always returns a MismatchedInputException
with the following message:
...MismatchedInputException: Root name ('builders')
does not match expected ('Builder[]') for type `[LModel.Attributes.Builder;`
Below is my code for my DTO:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
@JsonRootName("builders")
public class Builder {
private String id;
private String builder;
@JsonProperty("id")
public void setId(String id) {
this.id = id;
}
@JsonProperty("name")
public void setBuilder(String builder) {
this.builder = builder;
}
public String getBuilder() {
return builder;
}
public String getId(){
return id;
}
}
And here we have our deserializer:
var json = response.body();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
var builders = mapper.readValue(json, Builder[].class);
And this is my JSON:
{
"builders": [
{
"id": 1,
"name": "Haley LLC"
},
{
"id": 2,
"name": "Stoltenberg, Mayert and Weimann"
},
{
"id": 3,
"name": "Ziemann Group"
},
{
"id": 4,
"name": "Monahan - Torp"
},
{
"id": 5,
"name": "Fritsch, Harber and Lemke"
}
]
}
3
Answers
Could you try with a wrapper class:
Annotation
@JsonRootName
would work as expect if there would be a single object, not a JSON-array. In this case, we need a different approach.You can prepare an
ObjectReader
by specifyingTypeReference
of typeList<Builder>
using methodObjectMapper.readerFor( TypeReference )
.And in order to unwrap this JSON-array, we can make use of the method
ObjectReader.withRootName()
.Here’s how it might look like:
Output:
Note
@JsonRootName
on top of theBuilder
class is not needed in this case. You can remove it, if you have no another cases with a singleBuilder
object being wrapped in the JSON.Also, applying deserialization feature
UNWRAP_ROOT_VALUE
is not required for this solution to work.You could just Deserialize to
Map<String, List<Builder>>
and thenget
by key "builders".Even semantically it’s not a bad representation because it is, after all, a JS Dictionary object with a list of Builders in it under the key "builders".