Edy Bourne Edy Bourne - 1 year ago 282
JSON Question

Jackson JSON not able to deserialize array of elements with custom root name?

I have a Json that looks like this:

"testEntities" : [ {
"id" : 1,
"floatNumber" : 0.006117165,
"floatNumberObject" : 0.15273619,
"intNumber" : -1155869325,
"intNumberObject" : 431529176,
"doubleNumber" : 0.41008081149220166,
"doubleNumberObject" : 0.20771484130971707,
"shortNumber" : 9364,
"shortNumberObject" : 13977,
"booleanValue" : true,
"booleanValueObject" : true,
"byteValue" : -79,
"charValue" : "e",
"charValueObject" : "b",
"creationDate" : 86400000
}, {
"id" : 2,
"floatNumber" : 0.9874208,
"floatNumberObject" : 0.45285606,
"intNumber" : -1154715079,
"intNumberObject" : 1260042744,
"doubleNumber" : 0.9014476240300544,
"doubleNumberObject" : 0.49682259343089075,
"shortNumber" : 483,
"shortNumberObject" : 18322,
"booleanValue" : false,
"booleanValueObject" : true,
"byteValue" : -73,
"charValue" : "c",
"charValueObject" : "r",
"creationDate" : 172800000
} ]

When I attempt to deserialize it, it fails with:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Root name 'testEntities' does not match expected ('TestObject[]') for type

I already enabled array deserialization:


is a custom name that Jackson knows nothing about. The
class has a custom annotation I created called
, to be used when the root element is a collection instead of a single instance:

public class TestObject {

This annotation is needed in other places of the system as well.

I want it to use it the same way it uses the
annotation, except that for arrays. So It could look for the root element as indicated by JsonRootName, and if none is found, it could look for @JsonRootNamePlural. All other root names in the JSON should be ignored by Jackson.

The question is, what should I override or customize to introduce this behavior?

Any help or pointers are greatly appreciated, thanks!!

Answer Source

Found the answer for my own question: Need to set on the object mapper a custom instance of JacksonAnnotationIntrospector which override the findRootName method, and there check if the class is array and if so look for the custom annotation in the array component class, like so:

    public PropertyName findRootName(AnnotatedClass ac) {
        // if this is an array, look for JsonRootNamePlural annotation in
        // the base type for the array (the so called array component)
        if (ac.getRawType().isArray()) {
            Class<?> arrayComponent = ac.getRawType().getComponentType();

            JsonRootNamePlural ann = arrayComponent.getAnnotation(JsonRootNamePlural.class);
            if (ann != null) {
                return PropertyName.construct(ann.value(), null);


        // super class will look for default @JsonRootName annotation
        return super.findRootName(ac);

Hope this will help others,