diff --git a/jackson/pom.xml b/jackson/pom.xml
index 9f8e652359..e9008a81a7 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -1,4 +1,5 @@
-
+
4.0.0
com.baeldung
jackson
@@ -54,6 +55,12 @@
com.fasterxml.jackson.datatype
jackson-datatype-joda
${jackson.version}
+
+
+
+ com.fasterxml.jackson.module
+ jackson-module-jsonSchema
+ 2.6.0
@@ -168,4 +175,4 @@
-
\ No newline at end of file
+
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/AppendBean.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/AppendBean.java
new file mode 100644
index 0000000000..26b0b2681c
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/AppendBean.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/ExtraAnnotationTest.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/ExtraAnnotationTest.java
new file mode 100644
index 0000000000..330e15a239
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/ExtraAnnotationTest.java
@@ -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 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 beanList = deserializedContainer.getBeans();
+ assertThat(beanList.get(0), instanceOf(TypeIdResolverStructure.FirstBean.class));
+ assertThat(beanList.get(1), instanceOf(TypeIdResolverStructure.LastBean.class));
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/IdentityReferenceBean.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/IdentityReferenceBean.java
new file mode 100644
index 0000000000..831f3efc79
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/IdentityReferenceBean.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/NamingBean.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/NamingBean.java
new file mode 100644
index 0000000000..eed4ec9237
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/NamingBean.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/POJOBuilderBean.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/POJOBuilderBean.java
new file mode 100644
index 0000000000..d285ce6870
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/POJOBuilderBean.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/PropertyDescriptionBean.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/PropertyDescriptionBean.java
new file mode 100644
index 0000000000..05038aef65
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/PropertyDescriptionBean.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/TypeIdBean.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/TypeIdBean.java
new file mode 100644
index 0000000000..6969c3df73
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/TypeIdBean.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/annotation/extra/TypeIdResolverStructure.java b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/TypeIdResolverStructure.java
new file mode 100644
index 0000000000..07f44b5a77
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/annotation/extra/TypeIdResolverStructure.java
@@ -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 beans;
+
+ public List getBeans() {
+ return beans;
+ }
+
+ public void setBeans(List 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceAnnotationStructure.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceAnnotationStructure.java
new file mode 100644
index 0000000000..a873d3e3c4
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceAnnotationStructure.java
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceMixinOrIntrospection.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceMixinOrIntrospection.java
new file mode 100644
index 0000000000..bca9572fc1
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceMixinOrIntrospection.java
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceTest.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceTest.java
new file mode 100644
index 0000000000..5680f870a4
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/IgnoranceTest.java
@@ -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 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 vehicles = new ArrayList<>();
+ vehicles.add(sedan);
+ vehicles.add(crossover);
+
+ return mapper.writeValueAsString(vehicles);
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeConstructorStructure.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeConstructorStructure.java
new file mode 100644
index 0000000000..aca627a593
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeConstructorStructure.java
@@ -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 vehicles;
+
+ public List getVehicles() {
+ return vehicles;
+ }
+
+ public void setVehicles(List 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeConversionStructure.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeConversionStructure.java
new file mode 100644
index 0000000000..babff8f255
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeConversionStructure.java
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeHandlingTest.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeHandlingTest.java
new file mode 100644
index 0000000000..eb373ff607
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/SubTypeHandlingTest.java
@@ -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 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);
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoAnnotatedStructure.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoAnnotatedStructure.java
new file mode 100644
index 0000000000..698fddfd60
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoAnnotatedStructure.java
@@ -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 vehicles;
+
+ public List getVehicles() {
+ return vehicles;
+ }
+
+ public void setVehicles(List 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoInclusionTest.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoInclusionTest.java
new file mode 100644
index 0000000000..67d953bcb3
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoInclusionTest.java
@@ -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 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 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));
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoStructure.java b/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoStructure.java
new file mode 100644
index 0000000000..2c48a6e980
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/inheritance/TypeInfoStructure.java
@@ -0,0 +1,96 @@
+package org.baeldung.jackson.inheritance;
+
+import java.util.List;
+
+public class TypeInfoStructure {
+ public static class Fleet {
+ private List vehicles;
+
+ public List getVehicles() {
+ return vehicles;
+ }
+
+ public void setVehicles(List 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/test/JacksonAnnotationTest.java b/jackson/src/test/java/org/baeldung/jackson/test/JacksonAnnotationTest.java
index c188e9bce1..068b54ca60 100644
--- a/jackson/src/test/java/org/baeldung/jackson/test/JacksonAnnotationTest.java
+++ b/jackson/src/test/java/org/baeldung/jackson/test/JacksonAnnotationTest.java
@@ -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")));
diff --git a/jackson/src/test/java/org/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java b/jackson/src/test/java/org/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
index 64614fb854..fe0b18e859 100644
--- a/jackson/src/test/java/org/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
+++ b/jackson/src/test/java/org/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
@@ -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);