jackson version: 2.9.8
package z.jack;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
public class Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static class Deserializer extends StdDeserializer<Animal> {
private final ObjectMapper mapper;
public Deserializer() {
super(Animal.class);
this.mapper = new ObjectMapper();
}
@Override
public Animal deserialize(JsonParser p, DeserializationContext context) throws IOException {
ObjectCodec codec = p.getCodec();
TreeNode treeNode = codec.readTree(p);
if (treeNode.get("lives") == null) {
return mapper.treeToValue(treeNode, Animal.class);
} else {
return codec.treeToValue(treeNode, Cat.class);
}
}
}
}
//-------
package z.jack;
public class Cat extends Animal {
private int lives;
public int getLives() {
return lives;
}
public void setLives(int lives) {
this.lives = lives;
}
}
//----------------
package z.jack;
import java.util.List;
public class Zoo {
private List<Animal> animals;
public List<Animal> getAnimals() {
return animals;
}
public void setAnimals(List<Animal> animals) {
this.animals = animals;
}
}
//---- test
package z.jack;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
public class JacksonPolyTest {
private ObjectMapper mapper;
@Before
public void setUp() {
SimpleModule module = new SimpleModule();
module.addDeserializer(Animal.class, new Animal.Deserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
this.mapper = mapper;
}
@Test
public void testJsonToParent() throws IOException {
List<Animal> animals = new ArrayList<>();
Animal a1 = new Animal();
a1.setName("what");
animals.add(a1);
Zoo zoo = new Zoo();
zoo.setAnimals(animals);
Writer w = new StringWriter();
mapper.writeValue(w, zoo);
String json = w.toString();
System.out.println(json);
Zoo deSerialized = mapper.readValue(json, Zoo.class);
assert "what".equals(deSerialized.getAnimals().get(0).getName());
}
@Test
public void testJsonToChild() throws IOException {
List<Animal> animals = new ArrayList<>();
Cat cat = new Cat();
cat.setName("cat");
cat.setLives(9);
animals.add(cat);
Zoo zoo = new Zoo();
zoo.setAnimals(animals);
String json = mapper.writeValueAsString(zoo);
System.out.println(json);
Zoo deSerialized = mapper.readValue(json, Zoo.class);
assert "cat".equals(deSerialized.getAnimals().get(0).getName());
assert 9 == (((Cat) deSerialized.getAnimals().get(0)).getLives());
}
}