This question is similar to include class name in all objects serialized by jackson but I want to configure this by default without using annotations on each class. Preferably I'd like to add a field
to the serialized json, such as _class
or _type
that contains the class name of the serialized class (preferably not event fully qualified, but I'm ok with that). I'm using Jackson 2.11.1.
For example let's say I have this interface:
public interface MyInterface {}
and two implementations:
public class MyClass1 implements MyInterface {
private String something;
public String getSomething() {
return something;
}
public void setSomething(String something) {
this.something = something;
}
}
and
public class MyClass2 implements MyInterface {
private String somethingElse;
public String getSomethingElse() {
return somethingElse;
}
public void setSomethingElse(String somethingElse) {
this.somethingElse = somethingElse;
}
}
I'd like to be able to serialize instances of MyClass1
and MyClass2
so that I can deserialize them as MyInterface
(i.e. adding type information when serializing).
I've read in the documentation that you should be able to configure the ObjectMapper
like this to make it work:
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().build();
objectMapper.activateDefaultTyping(ptv); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE
But when I try this:
ObjectMapper objectMapper = new ObjectMapper();
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().build();
objectMapper.activateDefaultTyping(ptv); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE
MyClass1 myClass1 = new MyClass1();
myClass1.setSomething("something");
String json = objectMapper.writeValueAsString(myClass1);
MyInterface myInterface = objectMapper.readValue(json, MyInterface.class);
I get this exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class org.something.MyInterface
at [Source: (String)"{"something":"something"}"; line: 1, column: 1]
If I change the configuration to use ObjectMapper.DefaultTyping.EVERYTHING
then Jackson actually seem to wrap the type in an array but I still get an exception when trying to deserialize:
ObjectMapper objectMapper = new ObjectMapper();
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().build();
objectMapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING);
MyClass1 myClass1 = new MyClass1();
myClass1.setSomething("something");
String json = objectMapper.writeValueAsString(myClass1);
MyInterface myInterface = objectMapper.readValue(json, MyInterface.class);
the exception now is:
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'org.something.MyClass1' as a subtype of `org.something.MyInterface`: Configured `PolymorphicTypeValidator` (of type `com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator`) denied resolution
at [Source: (String)"["org.something.MyClass1",{"something":"something"}]"; line: 1, column: 53]
How can I resolve this?