Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to Jackson @JsonSubTypes

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;

    }
}
like image 634
user3153309 Avatar asked Jul 08 '14 12:07

user3153309


People also ask

Can Jackson ObjectMapper be reused?

ObjectMapper is the most important class in Jackson API that provides readValue() and writeValue() methods to transform JSON to Java Object and Java Object to JSON. ObjectMapper class can be reused and we can initialize it once as Singleton object.

Is @JsonProperty needed?

You definitely don't need all those @jsonProperty . Jackson mapper can be initialized to sereliazie/deserialize according to getters or private members, you of course need only the one you are using. By default it is by getters.

What is @JsonProperty used for?

@JsonProperty is used to mark non-standard getter/setter method to be used with respect to json property.

Does Jackson use getters and setters?

Jackson can't deserialize into private fields with its default settings. Because it needs getter or setter methods.


2 Answers

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.

like image 190
bertilmuth Avatar answered Sep 18 '22 22:09

bertilmuth


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

like image 27
SyntaX Avatar answered Sep 17 '22 22:09

SyntaX