inimene
inimene

Reputation: 1650

Jackson serialization error when class has generics in it

So I have a class that I want jackson to serialize.

public class MyClass<T extends MyInterface> {

   private T myGeneric;
   private String desc;

   ....
}

public interface MyInterface {
   String getSomeString();
}

public class MySubClass implements MyInterface {
  private String info;
  ....

  @Override
  public getSomeString() {
     return "";
  }
}

MyClass can have many types of other classes under it's myGeneric field. The problem is that when I pass my JSON to the server, then Jackson throws an error: problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information.

I investigated around and mostly only found examples of how to solve jackson problems with abstract classes but none for this kind of problem. I also tried using the @JsonTypeInfo and @JsonSubTypes annotations to list what kind of classes can go under MyClass but I am not sure if what I did was just wrong or not because it is hard to find any similar examples with them and the documentation in here: was not really helpful also.

Is this kind of problem solvable with Jackson annotations or I need to write a custom serializer for my class?

I am testing the serialization like this:

String json = "myJson";
ObjectMapper mapper = new ObjectMapper();
MyClass myClass = mapper.readValue(json, MyClass.class);

Upvotes: 1

Views: 1910

Answers (1)

AdamSkywalker
AdamSkywalker

Reputation: 11609

Jackson can't deserialize abstract types without additional info: when you have JSON with field

"myGeneric" : { "field1" : 1, "field2" : 2}

you have no idea what is the class of the myGeneric object.

So you have two options: use @JsonTypeInfo annotation or to create custom deserializer. Example:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
private T myGeneric ;

After that, serialized myGeneric field will look something like that:

"myGeneric" : { "field1" : 1, "field2" : 2, "@class" : "com.project.MySubClass"}

Deserializer will use this info to instantiate an object of correct type

Upvotes: 2

Related Questions