Skip to content

Instantly share code, notes, and snippets.

@hamishmorgan
Created November 15, 2014 10:34
Show Gist options
  • Save hamishmorgan/5a8b3fb8f36bc3582e62 to your computer and use it in GitHub Desktop.
Save hamishmorgan/5a8b3fb8f36bc3582e62 to your computer and use it in GitHub Desktop.
Example of polymorphic JSON de/serialization in Jackson (1.5+?)
package hiam.polyjson;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(Dog.class), @JsonSubTypes.Type(Cat.class)})
public abstract class Animal {
}
package hiam.polyjson;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import static java.util.Objects.hash;
@JsonTypeName("cat")
public class Cat extends Animal {
private final boolean likesCream;
private final int lives;
@JsonCreator
public Cat(@JsonProperty("likesCream") boolean likesCream, @JsonProperty("lives") int lives) {
this.likesCream = likesCream;
this.lives = lives;
}
public boolean isLikesCream() {
return likesCream;
}
public int getLives() {
return lives;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Cat)) return false;
Cat other = (Cat) o;
return likesCream == other.likesCream && lives == other.lives;
}
@Override
public int hashCode() {
return hash(likesCream, lives);
}
}
package hiam.polyjson;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import static java.util.Objects.hash;
@JsonTypeName("dog")
public class Dog extends Animal {
private final double barkVolumeDecibels;
@JsonCreator
public Dog(@JsonProperty("barkVolumeDecibels") double barkVolumeDecibels) {
this.barkVolumeDecibels = barkVolumeDecibels;
}
public double getBarkVolumeDecibels() {
return barkVolumeDecibels;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Dog)) return false;
return Double.compare(((Dog) o).barkVolumeDecibels, barkVolumeDecibels) == 0;
}
@Override
public int hashCode() {
return hash(barkVolumeDecibels);
}
}
package hiam.polyjson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
public class PolymorphicJsonTest {
private static final Animal DOG = new Dog(100);
private static final String DOG_JSON = "{\"type\":\"dog\",\"barkVolumeDecibels\":100.0}";
private static final Animal CAT = new Cat(true, 9);
private static final String CAT_JSON = "{\"type\":\"cat\",\"likesCream\":true,\"lives\":9}";
private ObjectMapper mapper = new ObjectMapper();
@Test
public void givenDog_whenWriteValueAsString_thenProducesExpectedJson() throws JsonProcessingException {
String json = mapper.writeValueAsString(DOG);
assertThat(json, equalTo(DOG_JSON));
}
@Test
public void givenCat_whenWriteValue_thenReturnsExpectedJson() throws JsonProcessingException {
String json = mapper.writeValueAsString(CAT);
assertThat(json, equalTo(CAT_JSON));
}
@Test
public void givenDogJson_whenReadValue_thenReturnsDog() throws IOException {
Animal animal = mapper.readValue(DOG_JSON, Animal.class);
assertThat(animal, instanceOf(Dog.class));
}
@Test
public void givenDogJson_whenReadValue_thenReturnsExpectedDog() throws IOException {
Animal animal = mapper.readValue(DOG_JSON, Animal.class);
assertThat(animal, equalTo(DOG));
}
@Test
public void givenCatJson_whenReadValue_thenReturnsCat() throws IOException {
Animal animal = mapper.readValue(CAT_JSON, Animal.class);
assertThat(animal, instanceOf(Cat.class));
}
@Test
public void givenCatJson_whenReadValue_thenReturnsExpectedCat() throws IOException {
Animal animal = mapper.readValue(CAT_JSON, Animal.class);
assertThat(animal, equalTo(CAT));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment