Jun Park
Jun Park

Reputation: 538

Spring @RequestBody for subclass. Alternative to @JsonTypeInfo?

Trying to acheive this

@RequestMapping
public String helloWorld(@RequestBody Parent interface){
    // do something with interface

}

where Parent is an Interface and Child1 and Child2 are implementations.

Because those are 3rd-party library .class files, I cannot use @JsonTypeInfo

Is there any workaround for this case?

Upvotes: 0

Views: 2161

Answers (1)

Darren Forsythe
Darren Forsythe

Reputation: 11411

Yes, you can use Jackson Mixin to provide jackson annotations to third party/untouchable classes.

https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations

This example is rather old, and provided from here but it still looks correct from the last time I implemented a MixIn,

http://programmerbruce.blogspot.co.uk/2011/05/deserialize-json-with-jackson-into.html

Example 5 from above,

{     "animals":
    [
       {"type":"dog","name":"Spike","breed":"mutt",        
       "leash_color":"red"},
       {"type":"cat","name":"Fluffy",
           "favorite_toy":"spider ring"}
     ]
   }


import java.io.File;
import java.util.Collection;

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.map.ObjectMapper;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(
        new CamelCaseNamingStrategy());
    mapper.getDeserializationConfig().addMixInAnnotations(
        Animal.class, PolymorphicAnimalMixIn.class);
    mapper.getSerializationConfig().addMixInAnnotations(
        Animal.class, PolymorphicAnimalMixIn.class);
    Zoo zoo = 
      mapper.readValue(new File("input_5.json"), Zoo.class);
    System.out.println(mapper.writeValueAsString(zoo));
  }
}

class Zoo
{
  public Collection<Animal> animals;
}

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @Type(value = Cat.class, name = "cat"),
    @Type(value = Dog.class, name = "dog") })
abstract class PolymorphicAnimalMixIn
{

}

abstract class Animal
{
  public String name;
}

class Dog extends Animal
{
  public String breed;
  public String leashColor;
}

class Cat extends Animal
{
  public String favoriteToy;
}

You can use Jackson2ObjectMapperBuilder or Jackson2ObjectMapperFactoryBean to register the MixIn within Spring Boot.

A working example of the above in Spring Boot world can be found here with tests verifying successful POST of Cat/Dog, e.g. the concrete implementation of the parent class.

https://github.com/Flaw101/springbootmixin

Upvotes: 2

Related Questions