Reputation: 151
Jackson framework provides annotation based approach to emit the type information during serialization process.
I do not want to use @JsonSubTypes annotation in my super class(Animal).
Instead I want to tell my SubClasses i.e Dog and Elephant that Animal is their parent.
Is there any approach to do so without using annotation in Animal class.
If yes, please provide example of to do the same if possible.
Following is case which I am trying to resolve.JSON which "test" receives, contains "type" field as "dog" or "elephant".
I want to register these two classes as subtypes of "Animal" class but don't want to use @JsonSubTypes in Animal.
Any help would be appreciated. Thanks in advance.
@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
abstract class Animal(){
private String sound;
private String type;
//getters and setters
}
@JsonTypeName("dog")
Class Dog extends Animal(){
//some attributes.
//getters and setters
}
@JsonTypeName("elephant")
Class Elephant extends Animal(){
//some attributes.
//getters and setters
}
@Controller
public class MyController {
//REST service
@RequestMapping( value = "test")
public @ResponseBody String save(@RequestBody Animal animal){
System.out.println(animal.getClass());
return success;
}
}
Upvotes: 11
Views: 9921
Reputation: 286
You can use the Moonwlker library.
With it, you can create an ObjectMapper like this:
ObjectMapper objectMapper = new ObjectMapper();
MoonwlkerModule module =
MoonwlkerModule.builder()
.fromProperty("type").toSubclassesOf(Animal.class)
.build();
objectMapper.registerModule(module);
And then use that mapper to (de)serialize. The Moonwlker website contains more details and configuration options.
Upvotes: 1
Reputation: 2120
This answer will help in achieving what you want, but in a slightly different way. Create a separate class with necessary configuration and register it as the serialization/deserialization configuration class for Animal class as below:
Configuration Class:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@Type(value = Elephant.class, name = "cat"),
@Type(value = Dog.class, name = "dog") })
abstract class PolymorphicAnimalMixIn {
//Empty Class
}
To serialize or deserialize:
ObjectMapper mapper = new ObjectMapper();
mapper.getDeserializationConfig().addMixInAnnotations(Animal.class, PolymorphicAnimalMixIn.class);
mapper.getSerializationConfig().addMixInAnnotations(Animal.class, PolymorphicAnimalMixIn.class);
//Sample class with collections of Animal
class Zoo {
public Collection<Animal> animals;
}
//To deserialize
Animal animal = mapper.readValue("string_payload", Zoo.class);
//To serialize
Animal animal = mapper.writeValueAsString(zoo);
Reference credit: example 5
Upvotes: 4