Add Jackson inheritance examples
This commit is contained in:
parent
365ec16879
commit
165ab9bf66
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue