Add Jackson inheritance examples

This commit is contained in:
David Morley 2016-03-10 05:22:38 -06:00
parent 365ec16879
commit 165ab9bf66
20 changed files with 1198 additions and 4 deletions

View File

@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>jackson</artifactId>
@ -54,6 +55,12 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
@ -168,4 +175,4 @@
</properties>
</project>
</project>

View File

@ -0,0 +1,31 @@
package org.baeldung.jackson.annotation.extra;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonAppend;
@JsonAppend(attrs = {@JsonAppend.Attr(value = "appendedProperty", include = JsonInclude.Include.ALWAYS)})
public class AppendBean {
private int id;
private String name;
public AppendBean(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,100 @@
package org.baeldung.jackson.annotation.extra;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
public class ExtraAnnotationTest {
@Test
public void whenUsingJsonIdentityReferenceAnnotation_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
IdentityReferenceBean bean = new IdentityReferenceBean(1, "Identity Reference Bean");
String jsonString = mapper.writeValueAsString(bean);
assertEquals("1", jsonString);
}
@Test
public void whenUsingJsonAppendAnnotation_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
AppendBean bean = new AppendBean(2, "Append Bean");
String jsonString = mapper.writeValueAsString(bean);
assertThat(jsonString, containsString("appendedProperty"));
}
@Test
public void whenUsingJsonNamingAnnotation_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
NamingBean bean = new NamingBean(3, "Naming Bean");
String jsonString = mapper.writeValueAsString(bean);
assertThat(jsonString, containsString("bean_name"));
}
@Test
public void whenUsingJsonPropertyDescriptionAnnotation_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
SchemaFactoryWrapper wrapper = new SchemaFactoryWrapper();
mapper.acceptJsonFormatVisitor(PropertyDescriptionBean.class, wrapper);
JsonSchema jsonSchema = wrapper.finalSchema();
String jsonString = mapper.writeValueAsString(jsonSchema);
assertThat(jsonString, containsString("This is a description of the name property"));
}
@Test
public void whenUsingJsonPOJOBuilderAnnotation_thenCorrect() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String jsonString = "{\"id\":5,\"name\":\"POJO Builder Bean\"}";
POJOBuilderBean bean = mapper.readValue(jsonString, POJOBuilderBean.class);
assertEquals(5, bean.getIdentity());
assertEquals("POJO Builder Bean", bean.getBeanName());
}
@Test
public void whenUsingJsonTypeIdAnnotation_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL);
TypeIdBean bean = new TypeIdBean(6, "Type Id Bean");
String jsonString = mapper.writeValueAsString(bean);
assertThat(jsonString, containsString("Type Id Bean"));
}
@Test
public void whenUsingJsonTypeIdResolverAnnotation_thenCorrect() throws IOException {
TypeIdResolverStructure.FirstBean bean1 = new TypeIdResolverStructure.FirstBean(1, "Bean 1");
TypeIdResolverStructure.LastBean bean2 = new TypeIdResolverStructure.LastBean(2, "Bean 2");
List<TypeIdResolverStructure.AbstractBean> beans = new ArrayList<>();
beans.add(bean1);
beans.add(bean2);
TypeIdResolverStructure.BeanContainer serializedContainer = new TypeIdResolverStructure.BeanContainer();
serializedContainer.setBeans(beans);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(serializedContainer);
assertThat(jsonString, containsString("bean1"));
assertThat(jsonString, containsString("bean2"));
TypeIdResolverStructure.BeanContainer deserializedContainer = mapper.readValue(jsonString, TypeIdResolverStructure.BeanContainer.class);
List<TypeIdResolverStructure.AbstractBean> beanList = deserializedContainer.getBeans();
assertThat(beanList.get(0), instanceOf(TypeIdResolverStructure.FirstBean.class));
assertThat(beanList.get(1), instanceOf(TypeIdResolverStructure.LastBean.class));
}
}

View File

@ -0,0 +1,33 @@
package org.baeldung.jackson.annotation.extra;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
public class IdentityReferenceBean {
private int id;
private String name;
public IdentityReferenceBean(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,31 @@
package org.baeldung.jackson.annotation.extra;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class NamingBean {
private int id;
private String beanName;
public NamingBean(int id, String beanName) {
this.id = id;
this.beanName = beanName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
}

View File

@ -0,0 +1,51 @@
package org.baeldung.jackson.annotation.extra;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
@JsonDeserialize(builder = POJOBuilderBean.BeanBuilder.class)
public class POJOBuilderBean {
private int identity;
private String beanName;
@JsonPOJOBuilder(buildMethodName = "createBean", withPrefix = "construct")
public static class BeanBuilder {
private int idValue;
private String nameValue;
public BeanBuilder constructId(int id) {
idValue = id;
return this;
}
public BeanBuilder constructName(String name) {
nameValue = name;
return this;
}
public POJOBuilderBean createBean() {
return new POJOBuilderBean(idValue, nameValue);
}
}
public POJOBuilderBean(int identity, String beanName) {
this.identity = identity;
this.beanName = beanName;
}
public int getIdentity() {
return identity;
}
public void setIdentity(int identity) {
this.identity = identity;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
}

View File

@ -0,0 +1,25 @@
package org.baeldung.jackson.annotation.extra;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
public class PropertyDescriptionBean {
private int id;
@JsonPropertyDescription("This is a description of the name property")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,30 @@
package org.baeldung.jackson.annotation.extra;
import com.fasterxml.jackson.annotation.JsonTypeId;
public class TypeIdBean {
private int id;
@JsonTypeId
private String name;
public TypeIdBean(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,130 @@
package org.baeldung.jackson.annotation.extra;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
public class TypeIdResolverStructure {
public static class BeanContainer {
private List<AbstractBean> beans;
public List<AbstractBean> getBeans() {
return beans;
}
public void setBeans(List<AbstractBean> beans) {
this.beans = beans;
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonTypeIdResolver(BeanIdResolver.class)
public static class AbstractBean {
private int id;
protected AbstractBean() {
}
protected AbstractBean(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
public static class FirstBean extends AbstractBean {
String firstName;
public FirstBean() {
}
public FirstBean(int id, String name) {
super(id);
setFirstName(name);
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String name) {
firstName = name;
}
}
public static class LastBean extends AbstractBean {
String lastName;
public LastBean() {
}
public LastBean(int id, String name) {
super(id);
setLastName(name);
}
public String getLastName() {
return lastName;
}
public void setLastName(String name) {
lastName = name;
}
}
public static class BeanIdResolver extends TypeIdResolverBase {
private JavaType superType;
@Override
public void init(JavaType baseType) {
superType = baseType;
}
@Override
public Id getMechanism() {
return Id.NAME;
}
@Override
public String idFromValue(Object obj) {
return idFromValueAndType(obj, obj.getClass());
}
@Override
public String idFromValueAndType(Object obj, Class<?> subType) {
String typeId = null;
switch (subType.getSimpleName()) {
case "FirstBean":
typeId = "bean1";
break;
case "LastBean":
typeId = "bean2";
}
return typeId;
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
Class<?> subType = null;
switch (id) {
case "bean1":
subType = FirstBean.class;
break;
case "bean2":
subType = LastBean.class;
}
return context.constructSpecializedType(superType, subType);
}
}
}

View File

@ -0,0 +1,96 @@
package org.baeldung.jackson.inheritance;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
public class IgnoranceAnnotationStructure {
public static abstract class Vehicle {
private String make;
private String model;
protected Vehicle() {
}
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
@JsonIgnoreProperties({ "model", "seatingCapacity" })
public static abstract class Car extends Vehicle {
private int seatingCapacity;
@JsonIgnore
private double topSpeed;
protected Car() {
}
protected Car(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
}
public static class Sedan extends Car {
public Sedan() {
}
public Sedan(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model, seatingCapacity, topSpeed);
}
}
public static class Crossover extends Car {
private double towingCapacity;
public Crossover() {
}
public Crossover(String make, String model, int seatingCapacity, double topSpeed, double towingCapacity) {
super(make, model, seatingCapacity, topSpeed);
this.towingCapacity = towingCapacity;
}
public double getTowingCapacity() {
return towingCapacity;
}
public void setTowingCapacity(double towingCapacity) {
this.towingCapacity = towingCapacity;
}
}
}

View File

@ -0,0 +1,91 @@
package org.baeldung.jackson.inheritance;
public class IgnoranceMixinOrIntrospection {
public static abstract class Vehicle {
private String make;
private String model;
protected Vehicle() {
}
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
public static abstract class Car extends Vehicle {
private int seatingCapacity;
private double topSpeed;
protected Car() {
}
protected Car(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
}
public static class Sedan extends Car {
public Sedan() {
}
public Sedan(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model, seatingCapacity, topSpeed);
}
}
public static class Crossover extends Car {
private double towingCapacity;
public Crossover() {
}
public Crossover(String make, String model, int seatingCapacity, double topSpeed, double towingCapacity) {
super(make, model, seatingCapacity, topSpeed);
this.towingCapacity = towingCapacity;
}
public double getTowingCapacity() {
return towingCapacity;
}
public void setTowingCapacity(double towingCapacity) {
this.towingCapacity = towingCapacity;
}
}
}

View File

@ -0,0 +1,92 @@
package org.baeldung.jackson.inheritance;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import org.junit.Test;
import java.util.List;
import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
public class IgnoranceTest {
private static abstract class CarMixIn {
@JsonIgnore
public String make;
@JsonIgnore
public String topSpeed;
}
private static class IgnoranceIntrospector extends JacksonAnnotationIntrospector {
private static final long serialVersionUID = 1422295680188892323L;
public boolean hasIgnoreMarker(AnnotatedMember m) {
return m.getDeclaringClass() == IgnoranceMixinOrIntrospection.Vehicle.class && m.getName() == "model" || m.getDeclaringClass() == IgnoranceMixinOrIntrospection.Car.class || m.getName() == "towingCapacity" || super.hasIgnoreMarker(m);
}
}
@Test
public void givenAnnotations_whenIgnoringProperties_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
IgnoranceAnnotationStructure.Sedan sedan = new IgnoranceAnnotationStructure.Sedan("Mercedes-Benz", "S500", 5, 250.0);
IgnoranceAnnotationStructure.Crossover crossover = new IgnoranceAnnotationStructure.Crossover("BMW", "X6", 5, 250.0, 6000.0);
List<IgnoranceAnnotationStructure.Vehicle> vehicles = new ArrayList<>();
vehicles.add(sedan);
vehicles.add(crossover);
String jsonDataString = mapper.writeValueAsString(vehicles);
assertThat(jsonDataString, containsString("make"));
assertThat(jsonDataString, not(containsString("model")));
assertThat(jsonDataString, not(containsString("seatingCapacity")));
assertThat(jsonDataString, not(containsString("topSpeed")));
assertThat(jsonDataString, containsString("towingCapacity"));
}
@Test
public void givenMixIns_whenIgnoringProperties_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(IgnoranceMixinOrIntrospection.Car.class, CarMixIn.class);
String jsonDataString = instantiateAndSerializeObjects(mapper);
assertThat(jsonDataString, not(containsString("make")));
assertThat(jsonDataString, containsString("model"));
assertThat(jsonDataString, containsString("seatingCapacity"));
assertThat(jsonDataString, not(containsString("topSpeed")));
assertThat(jsonDataString, containsString("towingCapacity"));
}
@Test
public void givenIntrospection_whenIgnoringProperties_thenCorrect() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new IgnoranceIntrospector());
String jsonDataString = instantiateAndSerializeObjects(mapper);
assertThat(jsonDataString, containsString("make"));
assertThat(jsonDataString, not(containsString("model")));
assertThat(jsonDataString, not(containsString("seatingCapacity")));
assertThat(jsonDataString, not(containsString("topSpeed")));
assertThat(jsonDataString, not(containsString("towingCapacity")));
}
private String instantiateAndSerializeObjects(ObjectMapper mapper) throws JsonProcessingException {
IgnoranceMixinOrIntrospection.Sedan sedan = new IgnoranceMixinOrIntrospection.Sedan("Mercedes-Benz", "S500", 5, 250.0);
IgnoranceMixinOrIntrospection.Crossover crossover = new IgnoranceMixinOrIntrospection.Crossover("BMW", "X6", 5, 250.0, 6000.0);
List<IgnoranceMixinOrIntrospection.Vehicle> vehicles = new ArrayList<>();
vehicles.add(sedan);
vehicles.add(crossover);
return mapper.writeValueAsString(vehicles);
}
}

View File

@ -0,0 +1,92 @@
package org.baeldung.jackson.inheritance;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class SubTypeConstructorStructure {
public static class Fleet {
private List<Vehicle> vehicles;
public List<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
}
public static abstract class Vehicle {
private String make;
private String model;
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
public static class Car extends Vehicle {
private int seatingCapacity;
private double topSpeed;
@JsonCreator
public Car(@JsonProperty("make") String make, @JsonProperty("model") String model, @JsonProperty("seating") int seatingCapacity, @JsonProperty("topSpeed") double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
}
public static class Truck extends Vehicle {
private double payloadCapacity;
@JsonCreator
public Truck(@JsonProperty("make") String make, @JsonProperty("model") String model, @JsonProperty("payload") double payloadCapacity) {
super(make, model);
this.payloadCapacity = payloadCapacity;
}
public double getPayloadCapacity() {
return payloadCapacity;
}
public void setPayloadCapacity(double payloadCapacity) {
this.payloadCapacity = payloadCapacity;
}
}
}

View File

@ -0,0 +1,87 @@
package org.baeldung.jackson.inheritance;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class SubTypeConversionStructure {
public static abstract class Vehicle {
private String make;
private String model;
protected Vehicle() {
}
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
public static class Car extends Vehicle {
@JsonIgnore
private int seatingCapacity;
@JsonIgnore
private double topSpeed;
public Car() {
}
public Car(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
}
public static class Truck extends Vehicle {
@JsonIgnore
private double payloadCapacity;
public Truck() {
}
public Truck(String make, String model, double payloadCapacity) {
super(make, model);
this.payloadCapacity = payloadCapacity;
}
public double getPayloadCapacity() {
return payloadCapacity;
}
public void setPayloadCapacity(double payloadCapacity) {
this.payloadCapacity = payloadCapacity;
}
}
}

View File

@ -0,0 +1,43 @@
package org.baeldung.jackson.inheritance;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class SubTypeHandlingTest {
@Test
public void givenSubTypes_whenConvertingObjects_thenDataValuesArePreserved() {
ObjectMapper mapper = new ObjectMapper();
SubTypeConversionStructure.Car car = new SubTypeConversionStructure.Car("Mercedes-Benz", "S500", 5, 250.0);
SubTypeConversionStructure.Truck truck = mapper.convertValue(car, SubTypeConversionStructure.Truck.class);
assertEquals("Mercedes-Benz", truck.getMake());
assertEquals("S500", truck.getModel());
}
@Test
public void givenSubType_whenNotUsingNoArgsConstructors_thenSucceed() throws IOException{
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
SubTypeConstructorStructure.Car car = new SubTypeConstructorStructure.Car("Mercedes-Benz", "S500", 5, 250.0);
SubTypeConstructorStructure.Truck truck = new SubTypeConstructorStructure.Truck("Isuzu", "NQR", 7500.0);
List<SubTypeConstructorStructure.Vehicle> vehicles = new ArrayList<>();
vehicles.add(car);
vehicles.add(truck);
SubTypeConstructorStructure.Fleet serializedFleet = new SubTypeConstructorStructure.Fleet();
serializedFleet.setVehicles(vehicles);
String jsonDataString = mapper.writeValueAsString(serializedFleet);
mapper.readValue(jsonDataString, SubTypeConstructorStructure.Fleet.class);
}
}

View File

@ -0,0 +1,102 @@
package org.baeldung.jackson.inheritance;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
public class TypeInfoAnnotatedStructure {
public static class Fleet {
private List<Vehicle> vehicles;
public List<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @Type(value = Car.class, name = "car"), @Type(value = Truck.class, name = "truck") })
public static abstract class Vehicle {
private String make;
private String model;
protected Vehicle() {
}
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
public static class Car extends Vehicle {
private int seatingCapacity;
private double topSpeed;
public Car() {
}
public Car(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
}
public static class Truck extends Vehicle {
private double payloadCapacity;
public Truck() {
}
public Truck(String make, String model, double payloadCapacity) {
super(make, model);
this.payloadCapacity = payloadCapacity;
}
public double getPayloadCapacity() {
return payloadCapacity;
}
public void setPayloadCapacity(double payloadCapacity) {
this.payloadCapacity = payloadCapacity;
}
}
}

View File

@ -0,0 +1,57 @@
package org.baeldung.jackson.inheritance;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf;
import org.junit.Test;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TypeInfoInclusionTest {
@Test
public void givenTypeInfo_whenAnnotatingGlobally_thenTypesAreCorrectlyRecovered() throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
TypeInfoStructure.Car car = new TypeInfoStructure.Car("Mercedes-Benz", "S500", 5, 250.0);
TypeInfoStructure.Truck truck = new TypeInfoStructure.Truck("Isuzu", "NQR", 7500.0);
List<TypeInfoStructure.Vehicle> vehicles = new ArrayList<>();
vehicles.add(car);
vehicles.add(truck);
TypeInfoStructure.Fleet serializedFleet = new TypeInfoStructure.Fleet();
serializedFleet.setVehicles(vehicles);
String jsonDataString = mapper.writeValueAsString(serializedFleet);
TypeInfoStructure.Fleet deserializedFleet = mapper.readValue(jsonDataString, TypeInfoStructure.Fleet.class);
assertThat(deserializedFleet.getVehicles().get(0), instanceOf(TypeInfoStructure.Car.class));
assertThat(deserializedFleet.getVehicles().get(1), instanceOf(TypeInfoStructure.Truck.class));
}
@Test
public void givenTypeInfo_whenAnnotatingPerClass_thenTypesAreCorrectlyRecovered() throws IOException {
ObjectMapper mapper = new ObjectMapper();
TypeInfoAnnotatedStructure.Car car = new TypeInfoAnnotatedStructure.Car("Mercedes-Benz", "S500", 5, 250.0);
TypeInfoAnnotatedStructure.Truck truck = new TypeInfoAnnotatedStructure.Truck("Isuzu", "NQR", 7500.0);
List<TypeInfoAnnotatedStructure.Vehicle> vehicles = new ArrayList<>();
vehicles.add(car);
vehicles.add(truck);
TypeInfoAnnotatedStructure.Fleet serializedFleet = new TypeInfoAnnotatedStructure.Fleet();
serializedFleet.setVehicles(vehicles);
String jsonDataString = mapper.writeValueAsString(serializedFleet);
TypeInfoAnnotatedStructure.Fleet deserializedFleet = mapper.readValue(jsonDataString, TypeInfoAnnotatedStructure.Fleet.class);
assertThat(deserializedFleet.getVehicles().get(0), instanceOf(TypeInfoAnnotatedStructure.Car.class));
assertThat(deserializedFleet.getVehicles().get(1), instanceOf(TypeInfoAnnotatedStructure.Truck.class));
}
}

View File

@ -0,0 +1,96 @@
package org.baeldung.jackson.inheritance;
import java.util.List;
public class TypeInfoStructure {
public static class Fleet {
private List<Vehicle> vehicles;
public List<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
}
public static abstract class Vehicle {
private String make;
private String model;
protected Vehicle() {
}
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
public static class Car extends Vehicle {
private int seatingCapacity;
private double topSpeed;
public Car() {
}
public Car(String make, String model, int seatingCapacity, double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
}
public static class Truck extends Vehicle {
private double payloadCapacity;
public Truck() {
}
public Truck(String make, String model, double payloadCapacity) {
super(make, model);
this.payloadCapacity = payloadCapacity;
}
public double getPayloadCapacity() {
return payloadCapacity;
}
public void setPayloadCapacity(double payloadCapacity) {
this.payloadCapacity = payloadCapacity;
}
}
}

View File

@ -345,7 +345,7 @@ public class JacksonAnnotationTest {
assertThat(result, containsString("John"));
final ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(String.class, MyMixInForString.class);
mapper.addMixIn(String.class, MyMixInForString.class);
result = mapper.writeValueAsString(user);
assertThat(result, not(containsString("John")));

View File

@ -87,7 +87,7 @@ public class JacksonSerializationIgnoreUnitTest {
@Test
public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException {
final ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(String.class, MyMixInForString.class);
mapper.addMixIn(String.class, MyMixInForString.class);
final MyDto dtoObject = new MyDto();
dtoObject.setBooleanValue(true);