Jerome VDL
Jerome VDL

Reputation: 3526

json jackson inner collection deserialize as LinkedHashMap instead of MyObject

I have the following object structure, on which I can't do any modification (this is a library and I don't have sources) :

class Foo {
   List bars; // with no generics (but this is a List<Bar>)
   Baz baz;
}

class Bar {
   Fiz fiz;
   Buz buz;
}

class Baz {
   int toto;
}

class Fiz {
   String titi;
}

class Buz {
   String tata;
}

And the following json :

{
   "bars" : [
      {
         "fiz" : {
             "titi" : "Hello"
         },
         "buz" : {
             "tata" : "World"
         }
      },
      {
         "fiz" : {
             "titi" : "Hola"
         },
         "buz" : {
             "tata" : "El Mundo"
         }
      }
   ],
   "baz" : {
       "toto" : 42
   }
}

I try to deserialize the json with the following code :

ObjectMapper mapper = new ObjectMapper();
// ... use the visibilityChecker because objects are immutable (no setter)
mapper.readValue(json, Foo.class);

I retrieve a List of LinkedHashMap instead of a List of Bar. I've check all others posts on the subject on stackoverflow, but each time, the list is at the top level so it is quite easy. I tried to use mixin without success, i tried with enableDefaultTyping but i got an error...

How can i do this ? I repeat I cannot modify the class files, add annotations, add intermediary objects, ... everything is in a library.

EDIT 21/12/2016 : I tried with Mixin :

abstract class FooMixin {
   @JsonProperty("bars")
   @JsonDeserialize(contentAs = Bar.class)
   List bars;
}

abstract class BarMixin {
   @JsonProperty("fiz") Fiz fiz;
   @JsonProperty("buz") Buz buz;
}

mapper.addMixin(Foo.class, FooMixin.class);
mapper.addMixin(Bar.class, BarMixin.class);

But got the same result (LinkedHashMap)...

Upvotes: 1

Views: 1902

Answers (1)

StaxMan
StaxMan

Reputation: 116502

Even if you don't control library code, you can still use mix-in annotations:

http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html

which is the way to go. One possibility here is to "mix in":

@JsonDeserialize(contentAs=Bar.class)

to augment type information; this needs to be before List-valued field or setter-method used to assign it.

Upvotes: 1

Related Questions