diff --git a/jackson-modules/jackson-annotations/README.md b/jackson-modules/jackson-annotations/README.md new file mode 100644 index 0000000000..783a06605b --- /dev/null +++ b/jackson-modules/jackson-annotations/README.md @@ -0,0 +1,9 @@ +## Jackson Annotations + +This module contains articles about Jackson annotations. + +### Relevant Articles: +- [Guide to @JsonFormat in Jackson](https://www.baeldung.com/jackson-jsonformat) +- [More Jackson Annotations](https://www.baeldung.com/jackson-advanced-annotations) +- [Jackson – Bidirectional Relationships](https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion) +- [Jackson JSON Views](https://www.baeldung.com/jackson-json-view-annotation) diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml new file mode 100644 index 0000000000..0da73e5791 --- /dev/null +++ b/jackson-modules/jackson-annotations/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + jackson-annotations + 0.0.1-SNAPSHOT + jackson-annotations + + + com.ossez + jackson-modules + 0.0.2-SNAPSHOT + + + + + com.fasterxml.jackson.module + jackson-module-jsonSchema + ${jackson.version} + + + io.rest-assured + json-path + ${rest-assured.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + jackson-annotations + + + src/main/resources + true + + + + + + 3.1.1 + + + \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListDeserializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListDeserializer.java new file mode 100644 index 0000000000..5e46c0abd5 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListDeserializer.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.bidirection; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class CustomListDeserializer extends StdDeserializer> { + + private static final long serialVersionUID = 1095767961632979804L; + + public CustomListDeserializer() { + this(null); + } + + public CustomListDeserializer(final Class vc) { + super(vc); + } + + @Override + public List deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException { + return new ArrayList(); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListSerializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListSerializer.java new file mode 100644 index 0000000000..376aba09e3 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/CustomListSerializer.java @@ -0,0 +1,32 @@ +package com.ossez.jackson.bidirection; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class CustomListSerializer extends StdSerializer> { + + private static final long serialVersionUID = 3698763098000900856L; + + public CustomListSerializer() { + this(null); + } + + public CustomListSerializer(final Class> t) { + super(t); + } + + @Override + public void serialize(final List items, final JsonGenerator generator, final SerializerProvider provider) throws IOException, JsonProcessingException { + final List ids = new ArrayList(); + for (final ItemWithSerializer item : items) { + ids.add(item.id); + } + generator.writeObject(ids); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/Item.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/Item.java new file mode 100644 index 0000000000..a3bc3af89d --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/Item.java @@ -0,0 +1,17 @@ +package com.ossez.jackson.bidirection; + +public class Item { + public int id; + public String itemName; + public User owner; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIdentity.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIdentity.java new file mode 100644 index 0000000000..d2ca1392ed --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIdentity.java @@ -0,0 +1,21 @@ +package com.ossez.jackson.bidirection; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class ItemWithIdentity { + public int id; + public String itemName; + public UserWithIdentity owner; + + public ItemWithIdentity() { + super(); + } + + public ItemWithIdentity(final int id, final String itemName, final UserWithIdentity owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIgnore.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIgnore.java new file mode 100644 index 0000000000..9cfa9e6056 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithIgnore.java @@ -0,0 +1,17 @@ +package com.ossez.jackson.bidirection; + +public class ItemWithIgnore { + public int id; + public String itemName; + public UserWithIgnore owner; + + public ItemWithIgnore() { + super(); + } + + public ItemWithIgnore(final int id, final String itemName, final UserWithIgnore owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithRef.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithRef.java new file mode 100644 index 0000000000..5db219f428 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithRef.java @@ -0,0 +1,21 @@ +package com.ossez.jackson.bidirection; + +import com.fasterxml.jackson.annotation.JsonBackReference; + +public class ItemWithRef { + public int id; + public String itemName; + + @JsonBackReference + public UserWithRef owner; + + public ItemWithRef() { + super(); + } + + public ItemWithRef(final int id, final String itemName, final UserWithRef owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithSerializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithSerializer.java new file mode 100644 index 0000000000..dc889d49e8 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithSerializer.java @@ -0,0 +1,17 @@ +package com.ossez.jackson.bidirection; + +public class ItemWithSerializer { + public int id; + public String itemName; + public UserWithSerializer owner; + + public ItemWithSerializer() { + super(); + } + + public ItemWithSerializer(final int id, final String itemName, final UserWithSerializer owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithView.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithView.java new file mode 100644 index 0000000000..c22a765b7c --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/ItemWithView.java @@ -0,0 +1,26 @@ +package com.ossez.jackson.bidirection; + +import com.ossez.jackson.bidirection.jsonview.Views; + +import com.fasterxml.jackson.annotation.JsonView; + +public class ItemWithView { + @JsonView(Views.Public.class) + public int id; + + @JsonView(Views.Public.class) + public String itemName; + + @JsonView(Views.Public.class) + public UserWithView owner; + + public ItemWithView() { + super(); + } + + public ItemWithView(final int id, final String itemName, final UserWithView owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/User.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/User.java new file mode 100644 index 0000000000..4f7cfadc05 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/User.java @@ -0,0 +1,24 @@ +package com.ossez.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +public class User { + public int id; + public String name; + public List userItems; + + public User() { + super(); + } + + public User(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final Item item) { + userItems.add(item); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIdentity.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIdentity.java new file mode 100644 index 0000000000..90baaca4db --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIdentity.java @@ -0,0 +1,28 @@ +package com.ossez.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class UserWithIdentity { + public int id; + public String name; + public List userItems; + + public UserWithIdentity() { + super(); + } + + public UserWithIdentity(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithIdentity item) { + userItems.add(item); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIgnore.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIgnore.java new file mode 100644 index 0000000000..19fb6b63fe --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithIgnore.java @@ -0,0 +1,28 @@ +package com.ossez.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class UserWithIgnore { + public int id; + public String name; + + @JsonIgnore + public List userItems; + + public UserWithIgnore() { + super(); + } + + public UserWithIgnore(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithIgnore item) { + userItems.add(item); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithRef.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithRef.java new file mode 100644 index 0000000000..8236103627 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithRef.java @@ -0,0 +1,28 @@ +package com.ossez.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonManagedReference; + +public class UserWithRef { + public int id; + public String name; + + @JsonManagedReference + public List userItems; + + public UserWithRef() { + super(); + } + + public UserWithRef(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList<>(); + } + + public void addItem(final ItemWithRef item) { + userItems.add(item); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithSerializer.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithSerializer.java new file mode 100644 index 0000000000..7b4f2d01d3 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithSerializer.java @@ -0,0 +1,30 @@ +package com.ossez.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class UserWithSerializer { + public int id; + public String name; + + @JsonSerialize(using = CustomListSerializer.class) + @JsonDeserialize(using = CustomListDeserializer.class) + public List userItems; + + public UserWithSerializer() { + super(); + } + + public UserWithSerializer(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithSerializer item) { + userItems.add(item); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithView.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithView.java new file mode 100644 index 0000000000..d1835e6a4e --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/UserWithView.java @@ -0,0 +1,33 @@ +package com.ossez.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.ossez.jackson.bidirection.jsonview.Views; + +import com.fasterxml.jackson.annotation.JsonView; + +public class UserWithView { + @JsonView(Views.Public.class) + public int id; + + @JsonView(Views.Public.class) + public String name; + + @JsonView(Views.Internal.class) + public List userItems; + + public UserWithView() { + super(); + } + + public UserWithView(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithView item) { + userItems.add(item); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/jsonview/Views.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/jsonview/Views.java new file mode 100644 index 0000000000..5f1dea2908 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/bidirection/jsonview/Views.java @@ -0,0 +1,9 @@ +package com.ossez.jackson.bidirection.jsonview; + +public class Views { + public static class Public { + } + + public static class Internal extends Public { + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/domain/Person.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/domain/Person.java new file mode 100644 index 0000000000..026d52cfaa --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/domain/Person.java @@ -0,0 +1,30 @@ +package com.ossez.jackson.domain; + +public class Person { + + private String firstName; + private String lastName; + + public Person(String firstName, String lastName) { + super(); + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} + diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/format/User.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/format/User.java new file mode 100644 index 0000000000..6a18331273 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/format/User.java @@ -0,0 +1,37 @@ +package com.ossez.jackson.format; + +import java.util.Date; + +import com.ossez.jackson.domain.Person; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * @author Jay Sridhar + * @version 1.0 + */ +public class User extends Person { + private String firstName; + private String lastName; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ") + private Date createdDate; + + public User(String firstName, String lastName) { + super(firstName, lastName); + this.createdDate = new Date(); + } + + public Date getCreatedDate() { + return createdDate; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ", locale = "en_GB") + public Date getCurrentDate() { + return new Date(); + } + + @JsonFormat(shape = JsonFormat.Shape.NUMBER) + public Date getDateNum() { + return new Date(); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Item.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Item.java new file mode 100644 index 0000000000..2d9fe2c1c6 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Item.java @@ -0,0 +1,36 @@ +package com.ossez.jackson.jsonview; + +import com.fasterxml.jackson.annotation.JsonView; + +public class Item { + @JsonView(Views.Public.class) + public int id; + + @JsonView(Views.Public.class) + public String itemName; + + @JsonView(Views.Internal.class) + public String ownerName; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final String ownerName) { + this.id = id; + this.itemName = itemName; + this.ownerName = ownerName; + } + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public String getOwnerName() { + return ownerName; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/MyBeanSerializerModifier.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/MyBeanSerializerModifier.java new file mode 100644 index 0000000000..5dd24a7790 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/MyBeanSerializerModifier.java @@ -0,0 +1,22 @@ +package com.ossez.jackson.jsonview; + +import java.util.List; + +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; + +public class MyBeanSerializerModifier extends BeanSerializerModifier { + + @Override + public List changeProperties(final SerializationConfig config, final BeanDescription beanDesc, final List beanProperties) { + for (int i = 0; i < beanProperties.size(); i++) { + final BeanPropertyWriter beanPropertyWriter = beanProperties.get(i); + if (beanPropertyWriter.getName() == "name") { + beanProperties.set(i, new UpperCasingWriter(beanPropertyWriter)); + } + } + return beanProperties; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/UpperCasingWriter.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/UpperCasingWriter.java new file mode 100644 index 0000000000..95dc39bc46 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/UpperCasingWriter.java @@ -0,0 +1,21 @@ +package com.ossez.jackson.jsonview; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; + +public class UpperCasingWriter extends BeanPropertyWriter { + final BeanPropertyWriter _writer; + + public UpperCasingWriter(final BeanPropertyWriter w) { + super(w); + _writer = w; + } + + @Override + public void serializeAsField(final Object bean, final JsonGenerator gen, final SerializerProvider prov) throws Exception { + String value = ((User) bean).name; + value = (value == null) ? "" : value.toUpperCase(); + gen.writeStringField("name", value); + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/User.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/User.java new file mode 100644 index 0000000000..2f602c8e1b --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/User.java @@ -0,0 +1,27 @@ +package com.ossez.jackson.jsonview; + +import com.fasterxml.jackson.annotation.JsonView; + +public class User { + public int id; + + @JsonView(Views.Public.class) + public String name; + + public User() { + super(); + } + + public User(final int id, final String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Views.java b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Views.java new file mode 100644 index 0000000000..26e3c91a66 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/ossez/jackson/jsonview/Views.java @@ -0,0 +1,9 @@ +package com.ossez.jackson.jsonview; + +public class Views { + public static class Public { + } + + public static class Internal extends Public { + } +} diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AdvancedAnnotationsUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AdvancedAnnotationsUnitTest.java new file mode 100644 index 0000000000..f610d69724 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AdvancedAnnotationsUnitTest.java @@ -0,0 +1,133 @@ +package com.ossez.jackson.advancedannotations; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.ossez.jackson.advancedannotations.AppendBeans.BeanWithAppend; +import com.ossez.jackson.advancedannotations.AppendBeans.BeanWithoutAppend; +import com.ossez.jackson.advancedannotations.IdentityReferenceBeans.BeanWithIdentityReference; +import com.ossez.jackson.advancedannotations.IdentityReferenceBeans.BeanWithoutIdentityReference; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.module.jsonSchema.JsonSchema; +import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper; + +public class AdvancedAnnotationsUnitTest { + @Test + public void whenNotUsingJsonIdentityReferenceAnnotation_thenCorrect() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + BeanWithoutIdentityReference bean = new BeanWithoutIdentityReference(1, "Bean Without Identity Reference Annotation"); + String jsonString = mapper.writeValueAsString(bean); + + assertThat(jsonString, containsString("Bean Without Identity Reference Annotation")); + } + + @Test + public void whenUsingJsonIdentityReferenceAnnotation_thenCorrect() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + BeanWithIdentityReference bean = new BeanWithIdentityReference(1, "Bean With Identity Reference Annotation"); + String jsonString = mapper.writeValueAsString(bean); + + assertEquals("1", jsonString); + } + + @Test + public void whenNotUsingJsonAppendAnnotation_thenCorrect() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + + BeanWithoutAppend bean = new BeanWithoutAppend(2, "Bean Without Append Annotation"); + ObjectWriter writer = mapper.writerFor(BeanWithoutAppend.class) + .withAttribute("version", "1.0"); + String jsonString = writer.writeValueAsString(bean); + + assertThat(jsonString, not(containsString("version"))); + assertThat(jsonString, not(containsString("1.0"))); + } + + @Test + public void whenUsingJsonAppendAnnotation_thenCorrect() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + + BeanWithAppend bean = new BeanWithAppend(2, "Bean With Append Annotation"); + ObjectWriter writer = mapper.writerFor(BeanWithAppend.class) + .withAttribute("version", "1.0"); + String jsonString = writer.writeValueAsString(bean); + + assertThat(jsonString, containsString("version")); + assertThat(jsonString, containsString("1.0")); + } + + @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); + System.out.println(jsonString); + 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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AppendBeans.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AppendBeans.java new file mode 100644 index 0000000000..6f28dbe42b --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/AppendBeans.java @@ -0,0 +1,58 @@ +package com.ossez.jackson.advancedannotations; + +import com.fasterxml.jackson.databind.annotation.JsonAppend; + +public class AppendBeans { + public static class BeanWithoutAppend { + private int id; + private String name; + + public BeanWithoutAppend(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; + } + } + + @JsonAppend(attrs = { @JsonAppend.Attr(value = "version") }) + public static class BeanWithAppend { + private int id; + private String name; + + public BeanWithAppend(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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/IdentityReferenceBeans.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/IdentityReferenceBeans.java new file mode 100644 index 0000000000..a825b7c19c --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/IdentityReferenceBeans.java @@ -0,0 +1,62 @@ +package com.ossez.jackson.advancedannotations; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIdentityReference; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +public class IdentityReferenceBeans { + @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") + public static class BeanWithoutIdentityReference { + private int id; + private String name; + + public BeanWithoutIdentityReference(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; + } + } + + @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") + @JsonIdentityReference(alwaysAsId = true) + public static class BeanWithIdentityReference { + private int id; + private String name; + + public BeanWithIdentityReference(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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/NamingBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/NamingBean.java new file mode 100644 index 0000000000..93b84b1c2a --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/NamingBean.java @@ -0,0 +1,31 @@ +package com.ossez.jackson.advancedannotations; + +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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/POJOBuilderBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/POJOBuilderBean.java new file mode 100644 index 0000000000..682917edc5 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/POJOBuilderBean.java @@ -0,0 +1,51 @@ +package com.ossez.jackson.advancedannotations; + +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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/PropertyDescriptionBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/PropertyDescriptionBean.java new file mode 100644 index 0000000000..b9178a2777 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/PropertyDescriptionBean.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.advancedannotations; + +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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdBean.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdBean.java new file mode 100644 index 0000000000..532941c551 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdBean.java @@ -0,0 +1,30 @@ +package com.ossez.jackson.advancedannotations; + +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-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdResolverStructure.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdResolverStructure.java new file mode 100644 index 0000000000..eb65f1df70 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/advancedannotations/TypeIdResolverStructure.java @@ -0,0 +1,130 @@ +package com.ossez.jackson.advancedannotations; + +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-modules/jackson-annotations/src/test/java/com/ossez/jackson/bidirection/JacksonBidirectionRelationUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/bidirection/JacksonBidirectionRelationUnitTest.java new file mode 100644 index 0000000000..b04ac4da9d --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/bidirection/JacksonBidirectionRelationUnitTest.java @@ -0,0 +1,152 @@ +package com.ossez.jackson.bidirection; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; + +import com.ossez.jackson.bidirection.jsonview.Views; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonBidirectionRelationUnitTest { + + @Test (expected = JsonMappingException.class) + public void givenBidirectionRelation_whenSerializing_thenException() throws JsonProcessingException { + final User user = new User(1, "John"); + final Item item = new Item(2, "book", user); + user.addItem(item); + + new ObjectMapper().writeValueAsString(item); + } + + @Test + public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotationWithSerialization_thenCorrect() throws JsonProcessingException { + final UserWithRef user = new UserWithRef(1, "John"); + final ItemWithRef item = new ItemWithRef(2, "book", user); + user.addItem(item); + + final String itemJson = new ObjectMapper().writeValueAsString(item); + final String userJson = new ObjectMapper().writeValueAsString(user); + + assertThat(itemJson, containsString("book")); + assertThat(itemJson, not(containsString("John"))); + + assertThat(userJson, containsString("John")); + assertThat(userJson, containsString("userItems")); + assertThat(userJson, containsString("book")); + } + + @Test + public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotationWithDeserialization_thenCorrect() throws JsonProcessingException { + final UserWithRef user = new UserWithRef(1, "John"); + final ItemWithRef item = new ItemWithRef(2, "book", user); + user.addItem(item); + + final String itemJson = new ObjectMapper().writeValueAsString(item); + final String userJson = new ObjectMapper().writeValueAsString(user); + + final ItemWithRef itemRead = new ObjectMapper().readValue(itemJson, ItemWithRef.class); + final UserWithRef userRead = new ObjectMapper().readValue(userJson, UserWithRef.class); + + assertThat(itemRead.itemName, is("book")); + assertThat(itemRead.owner, nullValue()); + + assertThat(userRead.name, is("John")); + assertThat(userRead.userItems.get(0).itemName, is("book")); + } + + @Test + public void givenBidirectionRelation_whenUsingJsonIdentityInfo_thenCorrect() throws JsonProcessingException { + final UserWithIdentity user = new UserWithIdentity(1, "John"); + final ItemWithIdentity item = new ItemWithIdentity(2, "book", user); + user.addItem(item); + + final String result = new ObjectMapper().writeValueAsString(item); + + assertThat(result, containsString("book")); + assertThat(result, containsString("John")); + assertThat(result, containsString("userItems")); + } + + @Test + public void givenBidirectionRelation_whenUsingJsonIgnore_thenCorrect() throws JsonProcessingException { + final UserWithIgnore user = new UserWithIgnore(1, "John"); + final ItemWithIgnore item = new ItemWithIgnore(2, "book", user); + user.addItem(item); + + final String result = new ObjectMapper().writeValueAsString(item); + + assertThat(result, containsString("book")); + assertThat(result, containsString("John")); + assertThat(result, not(containsString("userItems"))); + } + + @Test + public void givenBidirectionRelation_whenUsingCustomSerializer_thenCorrect() throws JsonProcessingException { + final UserWithSerializer user = new UserWithSerializer(1, "John"); + final ItemWithSerializer item = new ItemWithSerializer(2, "book", user); + user.addItem(item); + + final String result = new ObjectMapper().writeValueAsString(item); + + assertThat(result, containsString("book")); + assertThat(result, containsString("John")); + assertThat(result, containsString("userItems")); + } + + @Test + public void givenBidirectionRelation_whenDeserializingUsingIdentity_thenCorrect() throws JsonProcessingException, IOException { + final String json = "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}"; + + final ItemWithIdentity item = new ObjectMapper().readerFor(ItemWithIdentity.class) + .readValue(json); + + assertEquals(2, item.id); + assertEquals("book", item.itemName); + assertEquals("John", item.owner.name); + } + + @Test + public void givenBidirectionRelation_whenUsingCustomDeserializer_thenCorrect() throws JsonProcessingException, IOException { + final String json = "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}"; + + final ItemWithSerializer item = new ObjectMapper().readerFor(ItemWithSerializer.class) + .readValue(json); + assertEquals(2, item.id); + assertEquals("book", item.itemName); + assertEquals("John", item.owner.name); + } + + @Test + public void givenBidirectionRelation_whenUsingPublicJsonView_thenCorrect() throws JsonProcessingException { + final UserWithView user = new UserWithView(1, "John"); + final ItemWithView item = new ItemWithView(2, "book", user); + user.addItem(item); + + final String result = new ObjectMapper().writerWithView(Views.Public.class) + .writeValueAsString(item); + + assertThat(result, containsString("book")); + assertThat(result, containsString("John")); + assertThat(result, not(containsString("userItems"))); + } + + @Test(expected = JsonMappingException.class) + public void givenBidirectionRelation_whenUsingInternalJsonView_thenException() throws JsonProcessingException { + final UserWithView user = new UserWithView(1, "John"); + final ItemWithView item = new ItemWithView(2, "book", user); + user.addItem(item); + + new ObjectMapper().writerWithView(Views.Internal.class) + .writeValueAsString(item); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/format/JsonFormatUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/format/JsonFormatUnitTest.java new file mode 100644 index 0000000000..5771df25f7 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/format/JsonFormatUnitTest.java @@ -0,0 +1,37 @@ +package com.ossez.jackson.format; + +import java.util.Date; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.Test; + +import static io.restassured.path.json.JsonPath.from; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Percentage.withPercentage; + +/** + * @author Jay Sridhar + * @version 1.0 + */ +public class JsonFormatUnitTest { + + @Test + public void whenSerializedDateFormat_thenCorrect() throws JsonProcessingException { + + User user = new User("Jay", "Sridhar"); + + String result = new ObjectMapper().writeValueAsString(user); + + // Expected to match: "2016-12-19@09:34:42.628+0000" + assertThat(from(result).getString("createdDate")).matches("\\d{4}\\-\\d{2}\\-\\d{2}@\\d{2}:\\d{2}:\\d{2}\\.\\d{3}\\+\\d{4}"); + + // Expected to be close to current time + long now = new Date().getTime(); + assertThat(from(result).getLong("dateNum")).isCloseTo(now, withPercentage(10.0)); + + } +} diff --git a/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/jsonview/JacksonJsonViewUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/jsonview/JacksonJsonViewUnitTest.java new file mode 100644 index 0000000000..e658982009 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/ossez/jackson/jsonview/JacksonJsonViewUnitTest.java @@ -0,0 +1,88 @@ +package com.ossez.jackson.jsonview; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; + +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ser.BeanSerializerFactory; +import com.fasterxml.jackson.databind.ser.SerializerFactory; + +public class JacksonJsonViewUnitTest { + + @Test + public void whenUseJsonViewToSerialize_thenCorrect() throws JsonProcessingException { + final User user = new User(1, "John"); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION); + + final String result = mapper.writerWithView(Views.Public.class) + .writeValueAsString(user); + + assertThat(result, containsString("John")); + assertThat(result, not(containsString("1"))); + } + + @Test + public void whenUsePublicView_thenOnlyPublicSerialized() throws JsonProcessingException { + final Item item = new Item(2, "book", "John"); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writerWithView(Views.Public.class) + .writeValueAsString(item); + + assertThat(result, containsString("book")); + assertThat(result, containsString("2")); + + assertThat(result, not(containsString("John"))); + } + + @Test + public void whenUseInternalView_thenAllSerialized() throws JsonProcessingException { + final Item item = new Item(2, "book", "John"); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writerWithView(Views.Internal.class) + .writeValueAsString(item); + + assertThat(result, containsString("book")); + assertThat(result, containsString("2")); + + assertThat(result, containsString("John")); + } + + @Test + public void whenUseJsonViewToDeserialize_thenCorrect() throws IOException { + final String json = "{\"id\":1,\"name\":\"John\"}"; + + final ObjectMapper mapper = new ObjectMapper(); + + final User user = mapper.readerWithView(Views.Public.class) + .forType(User.class) + .readValue(json); + assertEquals(1, user.getId()); + assertEquals("John", user.getName()); + } + + @Test + public void whenUseCustomJsonViewToSerialize_thenCorrect() throws JsonProcessingException { + final User user = new User(1, "John"); + final SerializerFactory serializerFactory = BeanSerializerFactory.instance.withSerializerModifier(new MyBeanSerializerModifier()); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializerFactory(serializerFactory); + + final String result = mapper.writerWithView(Views.Public.class) + .writeValueAsString(user); + assertThat(result, containsString("JOHN")); + assertThat(result, containsString("1")); + } +} diff --git a/jackson-modules/jackson-conversions-2/README.md b/jackson-modules/jackson-conversions-2/README.md new file mode 100644 index 0000000000..ca81512fa3 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/README.md @@ -0,0 +1,13 @@ +## Jackson 转换 + +本模块中包含有关 Jackson 转换(Jackson conversions)有关的文章。 + +### 相关文章: +- [Mapping a Dynamic JSON Object with Jackson](https://www.baeldung.com/jackson-mapping-dynamic-object) +- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field) +- [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json) +- [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv) +- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml) +- [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api) +- [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast) +- More articles: [[<-- prev]](../jackson-conversions) diff --git a/jackson-modules/jackson-conversions-2/pom.xml b/jackson-modules/jackson-conversions-2/pom.xml new file mode 100644 index 0000000000..58de10fbd9 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + jackson-conversions-2 + 0.0.1-SNAPSHOT + jackson-conversions-2 + + + com.ossez + jackson-modules + 0.0.2-SNAPSHOT + + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-datatype.version} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + ${jackson.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + jackson-conversions-2 + + + src/main/resources + true + + + + + + 2.9.8 + + + \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/JsonCsvConverter.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/JsonCsvConverter.java new file mode 100644 index 0000000000..b907b9301f --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/JsonCsvConverter.java @@ -0,0 +1,57 @@ +package com.ossez.jackson.csv; + +import java.io.File; +import java.io.IOException; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; +import com.fasterxml.jackson.dataformat.csv.CsvSchema.Builder; + +public class JsonCsvConverter { + + public static void JsonToCsv(File jsonFile, File csvFile) throws IOException { + JsonNode jsonTree = new ObjectMapper().readTree(jsonFile); + + Builder csvSchemaBuilder = CsvSchema.builder(); + JsonNode firstObject = jsonTree.elements().next(); + firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} ); + CsvSchema csvSchema = csvSchemaBuilder + .build() + .withHeader(); + + CsvMapper csvMapper = new CsvMapper(); + csvMapper.writerFor(JsonNode.class) + .with(csvSchema) + .writeValue(csvFile, jsonTree); + } + + public static void csvToJson(File csvFile, File jsonFile) throws IOException { + CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader(); + CsvMapper csvMapper = new CsvMapper(); + MappingIterator orderLines = csvMapper.readerFor(OrderLine.class) + .with(orderLineSchema) + .readValues(csvFile); + + new ObjectMapper() + .configure(SerializationFeature.INDENT_OUTPUT, true) + .writeValue(jsonFile, orderLines.readAll()); + } + + public static void JsonToFormattedCsv(File jsonFile, File csvFile) throws IOException { + CsvMapper csvMapper = new CsvMapper(); + CsvSchema csvSchema = csvMapper + .schemaFor(OrderLineForCsv.class) + .withHeader(); + csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class); + + OrderLine[] orderLines = new ObjectMapper() + .readValue(jsonFile, OrderLine[].class); + csvMapper.writerFor(OrderLine[].class) + .with(csvSchema) + .writeValue(csvFile, orderLines); + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLine.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLine.java new file mode 100644 index 0000000000..7c028aa70c --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLine.java @@ -0,0 +1,49 @@ +package com.ossez.jackson.csv; + +import java.math.BigDecimal; + +public class OrderLine { + private String item; + private int quantity; + private BigDecimal unitPrice; + + public OrderLine() { + + } + + public OrderLine(String item, int quantity, BigDecimal unitPrice) { + super(); + this.item = item; + this.quantity = quantity; + this.unitPrice = unitPrice; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public BigDecimal getUnitPrice() { + return unitPrice; + } + + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } + + @Override + public String toString() { + return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]"; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLineForCsv.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLineForCsv.java new file mode 100644 index 0000000000..7e89d12a1c --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/csv/OrderLineForCsv.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.csv; + +import java.math.BigDecimal; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({ + "count", + "name" +}) +public abstract class OrderLineForCsv { + + @JsonProperty("name") + private String item; + + @JsonProperty("count") + private int quantity; + + @JsonIgnore + private BigDecimal unitPrice; + + +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/Product.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/Product.java new file mode 100644 index 0000000000..2b1b5b995e --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/Product.java @@ -0,0 +1,39 @@ +package com.ossez.jackson.dynamicobject; + +import java.util.LinkedHashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonAnySetter; + +public class Product { + + private String name; + private String category; + private Map details = new LinkedHashMap<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public Map getDetails() { + return details; + } + + @JsonAnySetter + public void setDetail(String key, Object value) { + details.put(key, value); + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductJsonNode.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductJsonNode.java new file mode 100644 index 0000000000..5c399a8411 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductJsonNode.java @@ -0,0 +1,35 @@ +package com.ossez.jackson.dynamicobject; + +import com.fasterxml.jackson.databind.JsonNode; + +public class ProductJsonNode { + + private String name; + private String category; + private JsonNode details; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public JsonNode getDetails() { + return details; + } + + public void setDetails(JsonNode details) { + this.details = details; + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductMap.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductMap.java new file mode 100644 index 0000000000..290bb50ef6 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/dynamicobject/ProductMap.java @@ -0,0 +1,35 @@ +package com.ossez.jackson.dynamicobject; + +import java.util.Map; + +public class ProductMap { + + private String name; + private String category; + private Map details; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public Map getDetails() { + return details; + } + + public void setDetails(Map details) { + this.details = details; + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/multiplefields/Weather.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/multiplefields/Weather.java new file mode 100644 index 0000000000..45d0322bfa --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/multiplefields/Weather.java @@ -0,0 +1,44 @@ +package com.ossez.jackson.multiplefields; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Weather { + + @JsonProperty("location") + @JsonAlias("place") + private String location; + + @JsonProperty("temp") + @JsonAlias("temperature") + private int temp; + + @JsonProperty("outlook") + @JsonAlias("weather") + private String outlook; + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public int getTemp() { + return temp; + } + + public void setTemp(int temp) { + this.temp = temp; + } + + public String getOutlook() { + return outlook; + } + + public void setOutlook(String outlook) { + this.outlook = outlook; + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/Book.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/Book.java new file mode 100644 index 0000000000..9f0dd4db28 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/Book.java @@ -0,0 +1,70 @@ +package com.ossez.jackson.tocollection; + + +import java.util.Objects; + +public class Book { + private Integer bookId; + private String title; + private String author; + + public Book() {} + + public Book(Integer bookId, String title, String author) { + this.bookId = bookId; + this.title = title; + this.author = author; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Book)) { + return false; + } + + Book book = (Book) o; + + if (!Objects.equals(bookId, book.bookId)) { + return false; + } + if (!Objects.equals(title, book.title)) { + return false; + } + return Objects.equals(author, book.author); + } + + @Override + public int hashCode() { + int result = bookId != null ? bookId.hashCode() : 0; + result = 31 * result + (title != null ? title.hashCode() : 0); + result = 31 * result + (author != null ? author.hashCode() : 0); + return result; + } + + public Integer getBookId() { + return bookId; + } + + public void setBookId(Integer bookId) { + this.bookId = bookId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/JsonToCollectionUtil.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/JsonToCollectionUtil.java new file mode 100644 index 0000000000..f60a3cde5a --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/tocollection/JsonToCollectionUtil.java @@ -0,0 +1,24 @@ +package com.ossez.jackson.tocollection; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class JsonToCollectionUtil { + + private JsonToCollectionUtil(){} + + public static List jsonArrayToList(String json, Class elementClass) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass); + return objectMapper.readValue(json, listType); + } + + public static List jsonArrayToList2(String json, Class elementClass) throws IOException { + return new ObjectMapper().readValue(json, new TypeReference>() {}); + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Color.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Color.java new file mode 100644 index 0000000000..da3c3fa590 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Color.java @@ -0,0 +1,5 @@ +package com.ossez.jackson.xmlToJson; + +public enum Color { + PINK, BLUE, YELLOW, RED; +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Flower.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Flower.java new file mode 100644 index 0000000000..8963c52c27 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/xmlToJson/Flower.java @@ -0,0 +1,42 @@ +package com.ossez.jackson.xmlToJson; + +public class Flower { + + private String name; + + private Color color; + + private Integer petals; + + public Flower() { } + + public Flower(String name, Color color, Integer petals) { + this.name = name; + this.color = color; + this.petals = petals; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public Integer getPetals() { + return petals; + } + + public void setPetals(Integer petals) { + this.petals = petals; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/Order.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/Order.java new file mode 100644 index 0000000000..b9739544e9 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/Order.java @@ -0,0 +1,68 @@ +package com.ossez.jackson.yaml; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +public class Order { + private String orderNo; + private LocalDate date; + private String customerName; + private List orderLines; + + public Order() { + + } + + public Order(String orderNo, LocalDate date, String customerName, List orderLines) { + super(); + this.orderNo = orderNo; + this.date = date; + this.customerName = customerName; + this.orderLines = orderLines; + } + + public String getOrderNo() { + return orderNo; + } + + public void setOrderNo(String orderNo) { + this.orderNo = orderNo; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public List getOrderLines() { + if (orderLines == null) { + orderLines = new ArrayList<>(); + } + return orderLines; + } + + public void setOrderLines(List orderLines) { + if (orderLines == null) { + orderLines = new ArrayList<>(); + } + this.orderLines = orderLines; + } + + @Override + public String toString() { + return "Order [orderNo=" + orderNo + ", date=" + date + ", customerName=" + customerName + ", orderLines=" + orderLines + "]"; + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/OrderLine.java b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/OrderLine.java new file mode 100644 index 0000000000..c30a5fd120 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/ossez/jackson/yaml/OrderLine.java @@ -0,0 +1,49 @@ +package com.ossez.jackson.yaml; + +import java.math.BigDecimal; + +public class OrderLine { + private String item; + private int quantity; + private BigDecimal unitPrice; + + public OrderLine() { + + } + + public OrderLine(String item, int quantity, BigDecimal unitPrice) { + super(); + this.item = item; + this.quantity = quantity; + this.unitPrice = unitPrice; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public BigDecimal getUnitPrice() { + return unitPrice; + } + + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } + + @Override + public String toString() { + return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]"; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.csv b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.csv new file mode 100644 index 0000000000..e15e12f2bf --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.csv @@ -0,0 +1,3 @@ +item,quantity,unitPrice +"No. 9 Sprockets",12,1.23 +"Widget (10mm)",4,3.45 diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.json b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.json new file mode 100644 index 0000000000..64f18e1673 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/resources/csv/orderLines.json @@ -0,0 +1,9 @@ +[ { + "item" : "No. 9 Sprockets", + "quantity" : 12, + "unitPrice" : 1.23 +}, { + "item" : "Widget (10mm)", + "quantity" : 4, + "unitPrice" : 3.45 +} ] \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json new file mode 100644 index 0000000000..6daf426736 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json @@ -0,0 +1,13 @@ +[ { + "bookId" : 1, + "title" : "A Song of Ice and Fire", + "author" : "George R. R. Martin" +}, { + "bookId" : 2, + "title" : "The Hitchhiker's Guide to the Galaxy", + "author" : "Douglas Adams" +}, { + "bookId" : 3, + "title" : "Hackers And Painters", + "author" : "Paul Graham" +} ] diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml new file mode 100644 index 0000000000..b2f951315b --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml @@ -0,0 +1,17 @@ + + + 1 + A Song of Ice and Fire + George R. R. Martin + + + 2 + The Hitchhiker's Guide to the Galaxy + Douglas Adams + + + 3 + Hackers And Painters + Paul Graham + + diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/csv/CsvUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/csv/CsvUnitTest.java new file mode 100644 index 0000000000..31f49da723 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/csv/CsvUnitTest.java @@ -0,0 +1,65 @@ +package com.ossez.jackson.csv; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.google.common.io.Files; + +public class CsvUnitTest { + + private File csvFromJson; + private File jsonFromCsv; + private File formattedCsvFromJson; + + @Before + public void setup() { + csvFromJson = new File("src/main/resources/csv/csvFromJson.csv"); + jsonFromCsv = new File("src/main/resources/csv/jsonFromCsv.json"); + formattedCsvFromJson = new File("src/main/resources/csv/formattedCsvFromJson.csv"); + } + + @After + public void cleanup() { + csvFromJson.deleteOnExit(); + jsonFromCsv.deleteOnExit(); + formattedCsvFromJson.deleteOnExit(); + } + + @Test + public void givenJsonInput_thenWriteCsv() throws JsonParseException, JsonMappingException, IOException { + JsonCsvConverter.JsonToCsv(new File("src/main/resources/csv/orderLines.json"), csvFromJson); + + assertEquals(readFile(csvFromJson.getAbsolutePath()), readFile("src/test/resources/csv/expectedCsvFromJson.csv")); + } + + @Test + public void givenCsvInput_thenWritesJson() throws JsonParseException, JsonMappingException, IOException { + JsonCsvConverter.csvToJson(new File("src/main/resources/csv/orderLines.csv"), jsonFromCsv); + + assertEquals(readFile(jsonFromCsv.getAbsolutePath()), readFile("src/test/resources/csv/expectedJsonFromCsv.json")); + + } + + @Test + public void givenJsonInput_thenWriteFormattedCsvOutput() throws JsonParseException, JsonMappingException, IOException { + JsonCsvConverter.JsonToFormattedCsv(new File("src/main/resources/csv/orderLines.json"), formattedCsvFromJson); + + assertEquals(readFile(formattedCsvFromJson.getAbsolutePath()), readFile("src/test/resources/csv/expectedFormattedCsvFromJson.csv")); + + } + + private List readFile(String filename) throws IOException { + return Files.readLines(new File(filename), Charset.forName("utf-8")); + } + +}; \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/dynamicobject/DynamicObjectDeserializationUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/dynamicobject/DynamicObjectDeserializationUnitTest.java new file mode 100644 index 0000000000..f037bb398f --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/dynamicobject/DynamicObjectDeserializationUnitTest.java @@ -0,0 +1,69 @@ +package com.ossez.jackson.dynamicobject; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.util.Scanner; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class DynamicObjectDeserializationUnitTest { + + private ObjectMapper objectMapper; + + @BeforeEach + void setup() { + objectMapper = new ObjectMapper(); + } + + private String readResource(String path) { + try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) { + return scanner.useDelimiter("\\A").next(); + } + } + + @Test + void givenJsonString_whenParsingToJsonNode_thenItMustContainDynamicProperties() throws JsonParseException, JsonMappingException, IOException { + // given + String json = readResource("/deserialize-dynamic-object/embedded.json"); + + // when + ProductJsonNode product = objectMapper.readValue(json, ProductJsonNode.class); + + // then + assertThat(product.getName()).isEqualTo("Pear yPhone 72"); + assertThat(product.getDetails().get("audioConnector").asText()).isEqualTo("none"); + } + + @Test + void givenJsonString_whenParsingToMap_thenItMustContainDynamicProperties() throws JsonParseException, JsonMappingException, IOException { + // given + String json = readResource("/deserialize-dynamic-object/embedded.json"); + + // when + ProductMap product = objectMapper.readValue(json, ProductMap.class); + + // then + assertThat(product.getName()).isEqualTo("Pear yPhone 72"); + assertThat(product.getDetails().get("audioConnector")).isEqualTo("none"); + } + + @Test + void givenJsonString_whenParsingWithJsonAnySetter_thenItMustContainDynamicProperties() throws JsonParseException, JsonMappingException, IOException { + // given + String json = readResource("/deserialize-dynamic-object/flat.json"); + + // when + Product product = objectMapper.readValue(json, Product.class); + + // then + assertThat(product.getName()).isEqualTo("Pear yPhone 72"); + assertThat(product.getDetails().get("audioConnector")).isEqualTo("none"); + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/multiplefields/MapMultipleFieldsToSingleFieldUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/multiplefields/MapMultipleFieldsToSingleFieldUnitTest.java new file mode 100644 index 0000000000..fa8659bacd --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/multiplefields/MapMultipleFieldsToSingleFieldUnitTest.java @@ -0,0 +1,37 @@ +package com.ossez.jackson.multiplefields; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class MapMultipleFieldsToSingleFieldUnitTest { + + @Test + public void givenTwoJsonFormats_whenDeserialized_thenWeatherObjectsCreated() throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + + Weather weather = mapper.readValue("{" + + "\"location\": \"London\"," + + "\"temp\": 15," + + "\"weather\": \"Cloudy\"" + + "}", Weather.class); + + assertEquals("London", weather.getLocation()); + assertEquals("Cloudy", weather.getOutlook()); + assertEquals(15, weather.getTemp()); + + weather = mapper.readValue("{" + + "\"place\": \"Lisbon\"," + + "\"temperature\": 35," + + "\"outlook\": \"Sunny\"" + + "}", Weather.class); + + assertEquals("Lisbon", weather.getLocation()); + assertEquals("Sunny", weather.getOutlook()); + assertEquals(35, weather.getTemp()); + + } +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/streaming/StreamingAPIUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/streaming/StreamingAPIUnitTest.java new file mode 100644 index 0000000000..4e987a9d7c --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/streaming/StreamingAPIUnitTest.java @@ -0,0 +1,118 @@ +package com.ossez.jackson.streaming; + +import com.fasterxml.jackson.core.*; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.TestCase.assertEquals; + +public class StreamingAPIUnitTest { + + @Test + public void givenJsonGenerator_whenAppendJsonToIt_thenGenerateJson() throws IOException { + // given + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + JsonFactory jfactory = new JsonFactory(); + JsonGenerator jGenerator = jfactory.createGenerator(stream, JsonEncoding.UTF8); + + // when + jGenerator.writeStartObject(); + jGenerator.writeStringField("name", "Tom"); + jGenerator.writeNumberField("age", 25); + jGenerator.writeFieldName("address"); + jGenerator.writeStartArray(); + jGenerator.writeString("Poland"); + jGenerator.writeString("5th avenue"); + jGenerator.writeEndArray(); + jGenerator.writeEndObject(); + jGenerator.close(); + + // then + String json = new String(stream.toByteArray(), "UTF-8"); + assertEquals(json, "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}"); + } + + @Test + public void givenJson_whenReadItUsingStreamAPI_thenShouldCreateProperJsonObject() throws IOException { + // given + String json = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}"; + JsonFactory jfactory = new JsonFactory(); + JsonParser jParser = jfactory.createParser(json); + + String parsedName = null; + Integer parsedAge = null; + List addresses = new LinkedList<>(); + + // when + while (jParser.nextToken() != JsonToken.END_OBJECT) { + + String fieldname = jParser.getCurrentName(); + if ("name".equals(fieldname)) { + jParser.nextToken(); + parsedName = jParser.getText(); + + } + + if ("age".equals(fieldname)) { + jParser.nextToken(); + parsedAge = jParser.getIntValue(); + + } + + if ("address".equals(fieldname)) { + jParser.nextToken(); + + while (jParser.nextToken() != JsonToken.END_ARRAY) { + addresses.add(jParser.getText()); + } + } + + } + jParser.close(); + + // then + assertEquals(parsedName, "Tom"); + assertEquals(parsedAge, (Integer) 25); + assertEquals(addresses, Arrays.asList("Poland", "5th avenue")); + + } + + @Test + public void givenJson_whenWantToExtractPartOfIt_thenShouldExtractOnlyNeededFieldWithoutGoingThroughWholeJSON() throws IOException { + // given + String json = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}"; + JsonFactory jfactory = new JsonFactory(); + JsonParser jParser = jfactory.createParser(json); + + String parsedName = null; + Integer parsedAge = null; + List addresses = new LinkedList<>(); + + // when + while (jParser.nextToken() != JsonToken.END_OBJECT) { + + String fieldname = jParser.getCurrentName(); + + if ("age".equals(fieldname)) { + jParser.nextToken(); + parsedAge = jParser.getIntValue(); + return; + } + + } + jParser.close(); + + // then + assertNull(parsedName); + assertEquals(parsedAge, (Integer) 25); + assertTrue(addresses.isEmpty()); + + } +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java new file mode 100644 index 0000000000..bf340fbb74 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java @@ -0,0 +1,130 @@ +package com.ossez.jackson.tocollection; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +public class DeserializeToJavaCollectionUnitTest { + private ObjectMapper objectMapper; + private XmlMapper xmlMapper; + private List expectedBookList; + + + @BeforeEach + void setup() { + objectMapper = new ObjectMapper(); + xmlMapper = new XmlMapper(); + expectedBookList = Lists.newArrayList( + new Book(1, "A Song of Ice and Fire", "George R. R. Martin"), + new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"), + new Book(3, "Hackers And Painters", "Paul Graham")); + } + + private String readFile(String path) { + try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) { + return scanner.useDelimiter("\\A").next(); + } + } + + /*==================== + * JSON tests + *==================== + */ + @Test + void givenJsonString_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException { + String jsonString = readFile("/to-java-collection/books.json"); + List bookList = objectMapper.readValue(jsonString, ArrayList.class); + assertThat(bookList).size().isEqualTo(3); + assertThatExceptionOfType(ClassCastException.class) + .isThrownBy(() -> bookList.get(0).getBookId()) + .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*"); + } + + @Test + void givenJsonString_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException { + String jsonString = readFile("/to-java-collection/books.json"); + List bookList = objectMapper.readValue(jsonString, new TypeReference>() {}); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + @Test + void givenJsonString_whenDeserializingWithJavaType_thenGetExpectedList() throws JsonProcessingException { + String jsonString = readFile("/to-java-collection/books.json"); + CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class); + List bookList = objectMapper.readValue(jsonString, listType); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + @Test + void givenJsonString_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException { + String jsonString = readFile("/to-java-collection/books.json"); + JsonNode jsonNode = objectMapper.readTree(jsonString); + List bookList = objectMapper.convertValue(jsonNode, new TypeReference>() {}); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + @Test + void givenJsonString_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException { + String jsonString = readFile("/to-java-collection/books.json"); + JsonNode jsonNode = objectMapper.readTree(jsonString); + List bookList = objectMapper.convertValue(jsonNode, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class)); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + /*==================== + * XML tests + *==================== + */ + @Test + void givenXml_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException { + String xml = readFile("/to-java-collection/books.xml"); + List bookList = xmlMapper.readValue(xml, ArrayList.class); + assertThat(bookList).size().isEqualTo(3); + assertThatExceptionOfType(ClassCastException.class) + .isThrownBy(() -> bookList.get(0).getBookId()) + .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*"); + } + + @Test + void givenXml_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException { + String xml = readFile("/to-java-collection/books.xml"); + List bookList = xmlMapper.readValue(xml, new TypeReference>() {}); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + @Test + void givenXml_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException { + String xml = readFile("/to-java-collection/books.xml"); + List node = xmlMapper.readValue(xml, List.class); + List bookList = xmlMapper.convertValue(node, new TypeReference>() {}); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + @Test + void givenXml_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException { + String xml = readFile("/to-java-collection/books.xml"); + List node = xmlMapper.readValue(xml, List.class); + List bookList = xmlMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class)); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/JsonToCollectionUtilUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/JsonToCollectionUtilUnitTest.java new file mode 100644 index 0000000000..1cd14f3504 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/tocollection/JsonToCollectionUtilUnitTest.java @@ -0,0 +1,51 @@ +package com.ossez.jackson.tocollection; + +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; +import java.util.Scanner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +class JsonToCollectionUtilUnitTest { + + private List expectedBookList; + + + @BeforeEach + void setup() { + expectedBookList = Lists.newArrayList( + new Book(1, "A Song of Ice and Fire", "George R. R. Martin"), + new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"), + new Book(3, "Hackers And Painters", "Paul Graham")); + } + + private String readFile(String path) { + try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) { + return scanner.useDelimiter("\\A").next(); + } + } + + @Test + void givenJsonString_whenCalljsonArrayToList_thenGetExpectedList() throws IOException { + String jsonString = readFile("/to-java-collection/books.json"); + List bookList = JsonToCollectionUtil.jsonArrayToList(jsonString, Book.class); + assertThat(bookList.get(0)).isInstanceOf(Book.class); + assertThat(bookList).isEqualTo(expectedBookList); + } + + @Test + void givenJsonString_whenCalljsonArrayToList2_thenGetException() throws IOException { + String jsonString = readFile("/to-java-collection/books.json"); + List bookList = JsonToCollectionUtil.jsonArrayToList2(jsonString, Book.class); + assertThat(bookList).size().isEqualTo(3); + assertThatExceptionOfType(ClassCastException.class) + .isThrownBy(() -> bookList.get(0).getBookId()) + .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*"); + } + +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/xmlToJson/XmlToJsonUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/xmlToJson/XmlToJsonUnitTest.java new file mode 100644 index 0000000000..170b1db71e --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/xmlToJson/XmlToJsonUnitTest.java @@ -0,0 +1,43 @@ +package com.ossez.jackson.xmlToJson; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.junit.Test; + +import static org.junit.Assert.*; + +import java.io.IOException; + +public class XmlToJsonUnitTest { + + @Test + public void givenAnXML_whenUseDataBidingToConvertToJSON_thenReturnDataOK() throws IOException{ + String flowerXML = "PoppyRED9"; + + XmlMapper xmlMapper = new XmlMapper(); + Flower poppy = xmlMapper.readValue(flowerXML, Flower.class); + + assertEquals(poppy.getName(), "Poppy"); + assertEquals(poppy.getColor(), Color.RED); + assertEquals(poppy.getPetals(), new Integer(9)); + + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(poppy); + + assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":9}"); + } + + @Test + public void givenAnXML_whenUseATreeConvertToJSON_thenReturnDataOK() throws IOException { + String flowerXML = "PoppyRED9"; + + XmlMapper xmlMapper = new XmlMapper(); + JsonNode node = xmlMapper.readTree(flowerXML.getBytes()); + + ObjectMapper jsonMapper = new ObjectMapper(); + String json = jsonMapper.writeValueAsString(node); + + assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":\"9\"}"); + } +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/yaml/YamlUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/yaml/YamlUnitTest.java new file mode 100644 index 0000000000..92a008d17e --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/ossez/jackson/yaml/YamlUnitTest.java @@ -0,0 +1,69 @@ +package com.ossez.jackson.yaml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; + +public class YamlUnitTest { + private ObjectMapper mapper; + private File orderOutput; + + @Before + public void setup() { + mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER)); + mapper.findAndRegisterModules(); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + orderOutput = new File("src/test/resources/yaml/orderOutput.yaml"); + } + + @After + public void cleanup() { + orderOutput.deleteOnExit(); + } + + @Test + public void givenYamlInput_ObjectCreated() throws JsonParseException, JsonMappingException, IOException { + Order order = mapper.readValue(new File("src/test/resources/yaml/orderInput.yaml"), Order.class); + assertEquals("A001", order.getOrderNo()); + assertEquals(LocalDate.parse("2019-04-17", DateTimeFormatter.ISO_DATE), order.getDate()); + assertEquals("Customer, Joe", order.getCustomerName()); + assertEquals(2, order.getOrderLines() + .size()); + } + + @Test + public void givenYamlObject_FileWritten() throws JsonGenerationException, JsonMappingException, IOException { + List lines = new ArrayList<>(); + lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP))); + lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP))); + Order order = new Order( + "B-9910", + LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE), + "Customer, Jane", + lines); + mapper.writeValue(orderOutput, order); + + File outputYaml = new File(orderOutput.getAbsolutePath()); + assertTrue(outputYaml.exists()); + } +} diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedCsvFromJson.csv b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedCsvFromJson.csv new file mode 100644 index 0000000000..e15e12f2bf --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedCsvFromJson.csv @@ -0,0 +1,3 @@ +item,quantity,unitPrice +"No. 9 Sprockets",12,1.23 +"Widget (10mm)",4,3.45 diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedFormattedCsvFromJson.csv b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedFormattedCsvFromJson.csv new file mode 100644 index 0000000000..5a60ba602a --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedFormattedCsvFromJson.csv @@ -0,0 +1,3 @@ +count,name +12,"No. 9 Sprockets" +4,"Widget (10mm)" diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedJsonFromCsv.json b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedJsonFromCsv.json new file mode 100644 index 0000000000..64f18e1673 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/resources/csv/expectedJsonFromCsv.json @@ -0,0 +1,9 @@ +[ { + "item" : "No. 9 Sprockets", + "quantity" : 12, + "unitPrice" : 1.23 +}, { + "item" : "Widget (10mm)", + "quantity" : 4, + "unitPrice" : 3.45 +} ] \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/embedded.json b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/embedded.json new file mode 100644 index 0000000000..e4f11f7f1f --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/embedded.json @@ -0,0 +1,8 @@ +{ + "name": "Pear yPhone 72", + "category": "cellphone", + "details": { + "displayAspectRatio": "97:3", + "audioConnector": "none" + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/flat.json b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/flat.json new file mode 100644 index 0000000000..799ea9339d --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/resources/deserialize-dynamic-object/flat.json @@ -0,0 +1,6 @@ +{ + "name": "Pear yPhone 72", + "category": "cellphone", + "displayAspectRatio": "97:3", + "audioConnector": "none" +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions-2/src/test/resources/yaml/orderInput.yaml b/jackson-modules/jackson-conversions-2/src/test/resources/yaml/orderInput.yaml new file mode 100644 index 0000000000..0aaa6186a2 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/resources/yaml/orderInput.yaml @@ -0,0 +1,11 @@ +orderNo: A001 +date: 2019-04-17 +customerName: Customer, Joe +orderLines: + - item: No. 9 Sprockets + quantity: 12 + unitPrice: 1.23 + - item: Widget (10mm) + quantity: 4 + unitPrice: 3.45 + \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/README.md b/jackson-modules/jackson-conversions/README.md new file mode 100644 index 0000000000..25e299800a --- /dev/null +++ b/jackson-modules/jackson-conversions/README.md @@ -0,0 +1,16 @@ +## Jackson 转换 + +这个模块主要是针对 Jackson 转换(Jackson Conversions) 有关的文章。 + +### Relevant Articles: +- [Jackson – Unmarshall to Collection/Array](https://www.baeldung.com/jackson-collection-array) +- [Jackson Date](https://www.baeldung.com/jackson-serialize-dates) +- [Jackson – Working with Maps and Nulls](https://www.baeldung.com/jackson-map-null-values-or-null-key) +- [Jackson – Decide What Fields Get Serialized/Deserialized](https://www.baeldung.com/jackson-field-serializable-deserializable-or-not) +- [XML Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-xml-serialization-and-deserialization) +- [Map Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-map) +- [How to Serialize and Deserialize Enums with Jackson](https://www.baeldung.com/jackson-serialize-enums) +- [使用 Jackson – 将字符串转换为 JsonNode 对象](https://www.ossez.com/t/jackson-jsonnode/13724) +- [Mapping Nested Values with Jackson](https://www.baeldung.com/jackson-nested-values) +- [Deserialize Immutable Objects with Jackson](https://www.baeldung.com/jackson-deserialize-immutable-objects) +- More articles: [[next -->]](../jackson-conversions-2) diff --git a/jackson-modules/jackson-conversions/pom.xml b/jackson-modules/jackson-conversions/pom.xml new file mode 100644 index 0000000000..f11e2b35fd --- /dev/null +++ b/jackson-modules/jackson-conversions/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + jackson-conversions + 0.0.1-SNAPSHOT + jackson-conversions + + + com.ossez + jackson-modules + 0.0.2-SNAPSHOT + + + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + + + jackson-conversions + + + src/main/resources + true + + + + + \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateDeserializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateDeserializer.java new file mode 100644 index 0000000000..6d0fe42cde --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateDeserializer.java @@ -0,0 +1,36 @@ +package com.ossez.jackson.date; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class CustomDateDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -5451717385630622729L; + private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + public CustomDateDeserializer() { + this(null); + } + + public CustomDateDeserializer(final Class vc) { + super(vc); + } + + @Override + public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException { + final String date = jsonparser.getText(); + try { + return formatter.parse(date); + } catch (final ParseException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateSerializer.java new file mode 100644 index 0000000000..db5d68c746 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateSerializer.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.date; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class CustomDateSerializer extends StdSerializer { + + private static final long serialVersionUID = -2894356342227378312L; + private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + public CustomDateSerializer() { + this(null); + } + + public CustomDateSerializer(final Class t) { + super(t); + } + + @Override + public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException { + gen.writeString(formatter.format(value)); + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateTimeSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateTimeSerializer.java new file mode 100644 index 0000000000..9d72a89292 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomDateTimeSerializer.java @@ -0,0 +1,32 @@ +package com.ossez.jackson.date; + +import java.io.IOException; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class CustomDateTimeSerializer extends StdSerializer { + + private static final long serialVersionUID = -3927232057990121460L; + + public CustomDateTimeSerializer() { + this(null); + } + + public CustomDateTimeSerializer(final Class t) { + super(t); + } + + private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"); + + @Override + public void serialize(final DateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException { + gen.writeString(formatter.print(value)); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomLocalDateTimeSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomLocalDateTimeSerializer.java new file mode 100644 index 0000000000..e6fea554d3 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/CustomLocalDateTimeSerializer.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.date; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class CustomLocalDateTimeSerializer extends StdSerializer { + + private static final long serialVersionUID = -7449444168934819290L; + private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + + public CustomLocalDateTimeSerializer() { + this(null); + } + + public CustomLocalDateTimeSerializer(final Class t) { + super(t); + } + + @Override + public void serialize(final LocalDateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException { + gen.writeString(formatter.format(value)); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/Event.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/Event.java new file mode 100644 index 0000000000..7762d5907b --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/Event.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.date; + +import java.util.Date; + +public class Event { + public String name; + public Date eventDate; + + public Event() { + super(); + } + + public Event(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithFormat.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithFormat.java new file mode 100644 index 0000000000..fe73f551c7 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithFormat.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.date; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; + +public class EventWithFormat { + public String name; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss") + public Date eventDate; + + public EventWithFormat() { + super(); + } + + public EventWithFormat(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithJodaTime.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithJodaTime.java new file mode 100644 index 0000000000..b9e0a8672f --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithJodaTime.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.date; + +import org.joda.time.DateTime; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class EventWithJodaTime { + public String name; + + @JsonSerialize(using = CustomDateTimeSerializer.class) + public DateTime eventDate; + + public EventWithJodaTime() { + super(); + } + + public EventWithJodaTime(final String name, final DateTime eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public DateTime getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDate.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDate.java new file mode 100644 index 0000000000..1562987b5b --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDate.java @@ -0,0 +1,33 @@ +package com.ossez.jackson.date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; + +import java.time.LocalDate; + +public class EventWithLocalDate { + public String name; + + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonSerialize(using = LocalDateSerializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") + public LocalDate eventDate; + + public EventWithLocalDate() {} + + public EventWithLocalDate(final String name, final LocalDate eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public LocalDate getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDateTime.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDateTime.java new file mode 100644 index 0000000000..f5d048fa93 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithLocalDateTime.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.date; + +import java.time.LocalDateTime; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class EventWithLocalDateTime { + public String name; + + @JsonSerialize(using = CustomLocalDateTimeSerializer.class) + public LocalDateTime eventDate; + + public EventWithLocalDateTime() { + super(); + } + + public EventWithLocalDateTime(final String name, final LocalDateTime eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public LocalDateTime getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithSerializer.java new file mode 100644 index 0000000000..595bcb8f76 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/date/EventWithSerializer.java @@ -0,0 +1,31 @@ +package com.ossez.jackson.date; + +import java.util.Date; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class EventWithSerializer { + public String name; + + @JsonDeserialize(using = CustomDateDeserializer.class) + @JsonSerialize(using = CustomDateSerializer.class) + public Date eventDate; + + public EventWithSerializer() { + super(); + } + + public EventWithSerializer(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/City.java new file mode 100644 index 0000000000..c86868de6e --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/City.java @@ -0,0 +1,15 @@ +package com.ossez.jackson.enums.deserialization; + +public class City { + + private Distance distance; + + public Distance getDistance() { + return distance; + } + + public void setDistance(Distance distance) { + this.distance = distance; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/Distance.java new file mode 100644 index 0000000000..96829dc3c9 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/Distance.java @@ -0,0 +1,31 @@ +package com.ossez.jackson.enums.deserialization; + +public enum Distance { + + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private double meters; + + private Distance(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public void setMeters(double meters) { + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } +} + diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/City.java new file mode 100644 index 0000000000..42425f8c07 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/City.java @@ -0,0 +1,15 @@ +package com.ossez.jackson.enums.deserialization.customdeserializer; + +public class City { + + private Distance distance; + + public Distance getDistance() { + return distance; + } + + public void setDistance(Distance distance) { + this.distance = distance; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/CustomEnumDeserializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/CustomEnumDeserializer.java new file mode 100644 index 0000000000..bb26606741 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/CustomEnumDeserializer.java @@ -0,0 +1,42 @@ +package com.ossez.jackson.enums.deserialization.customdeserializer; + +import java.io.IOException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class CustomEnumDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -1166032307856492833L; + + public CustomEnumDeserializer() { + this(null); + } + + public CustomEnumDeserializer(Class c) { + super(c); + } + + @Override + public Distance deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException { + + JsonNode node = jsonParser.getCodec().readTree(jsonParser); + + String unit = node.get("unit").asText(); + double meters = node.get("meters").asDouble(); + + for (Distance distance : Distance.values()) { + + if (distance.getUnit().equals(unit) && + Double.compare(distance.getMeters(), meters) == 0) { + + return distance; + } + } + + return null; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/Distance.java new file mode 100644 index 0000000000..b6053f01d8 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/customdeserializer/Distance.java @@ -0,0 +1,33 @@ +package com.ossez.jackson.enums.deserialization.customdeserializer; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = CustomEnumDeserializer.class) +public enum Distance { + + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private double meters; + + private Distance(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public void setMeters(double meters) { + this.meters = meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/City.java new file mode 100644 index 0000000000..734af4e548 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/City.java @@ -0,0 +1,15 @@ +package com.ossez.jackson.enums.deserialization.jsoncreator; + +public class City { + + private Distance distance; + + public Distance getDistance() { + return distance; + } + + public void setDistance(Distance distance) { + this.distance = distance; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/Distance.java new file mode 100644 index 0000000000..1c6bdfaad8 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsoncreator/Distance.java @@ -0,0 +1,48 @@ +package com.ossez.jackson.enums.deserialization.jsoncreator; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public enum Distance { + + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private double meters; + + private Distance(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public void setMeters(double meters) { + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + @JsonCreator + public static Distance forValues(@JsonProperty("unit") String unit, @JsonProperty("meters") double meters) { + + for (Distance distance : Distance.values()) { + if (distance.unit.equals(unit) && Double.compare(distance.meters, meters) == 0) { + + return distance; + } + } + + return null; + + } +} + diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/City.java new file mode 100644 index 0000000000..8d3ce1b326 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/City.java @@ -0,0 +1,15 @@ +package com.ossez.jackson.enums.deserialization.jsonproperty; + +public class City { + + private Distance distance; + + public Distance getDistance() { + return distance; + } + + public void setDistance(Distance distance) { + this.distance = distance; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/Distance.java new file mode 100644 index 0000000000..656a3dceee --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonproperty/Distance.java @@ -0,0 +1,51 @@ +package com.ossez.jackson.enums.deserialization.jsonproperty; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public enum Distance { + + @JsonProperty("distance-in-km") + KILOMETER("km", 1000), + + @JsonProperty("distance-in-miles") + MILE("miles", 1609.34), + + @JsonProperty("distance-in-meters") + METER("meters", 1), + + @JsonProperty("distance-in-inches") + INCH("inches", 0.0254), + + @JsonProperty("distance-in-cm") + CENTIMETER("cm", 0.01), + + @JsonProperty("distance-in-mm") + MILLIMETER("mm", 0.001); + + private String unit; + private double meters; + + private Distance(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public void setMeters(double meters) { + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} + + diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/City.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/City.java new file mode 100644 index 0000000000..bfe7f3c6e9 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/City.java @@ -0,0 +1,15 @@ +package com.ossez.jackson.enums.deserialization.jsonvalue; + +public class City { + + private Distance distance; + + public Distance getDistance() { + return distance; + } + + public void setDistance(Distance distance) { + this.distance = distance; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/Distance.java new file mode 100644 index 0000000000..530ddf9047 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/deserialization/jsonvalue/Distance.java @@ -0,0 +1,35 @@ +package com.ossez.jackson.enums.deserialization.jsonvalue; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum Distance { + + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private double meters; + + private Distance(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public void setMeters(double meters) { + this.meters = meters; + } + + @JsonValue + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} + diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/Distance.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/Distance.java new file mode 100644 index 0000000000..18ef758dfc --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/Distance.java @@ -0,0 +1,53 @@ +package com.ossez.jackson.enums.serialization; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * Use @JsonFormat to handle representation of Enum as JSON (available since Jackson 2.1.2) + * Use @JsonSerialize to configure a custom Jackson serializer + */ +// @JsonFormat(shape = JsonFormat.Shape.OBJECT) +@JsonSerialize(using = DistanceSerializer.class) +public enum Distance { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private Distance(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + /** + * Use @JsonValue to control marshalling output for an enum + */ + // @JsonValue + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + /** + * Usage example: Distance.MILE.convertFromMeters(1205.5); + */ + public double convertFromMeters(double distanceInMeters) { + return distanceInMeters / meters; + + } + + /** + * Usage example: Distance.MILE.convertToMeters(0.5); + */ + public double convertToMeters(double distanceInMeters) { + return distanceInMeters * meters; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/DistanceSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/DistanceSerializer.java new file mode 100644 index 0000000000..8fc9458daf --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/serialization/DistanceSerializer.java @@ -0,0 +1,32 @@ +package com.ossez.jackson.enums.serialization; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class DistanceSerializer extends StdSerializer { + + private static final long serialVersionUID = 1376504304439963619L; + + public DistanceSerializer() { + super(Distance.class); + } + + public DistanceSerializer(Class t) { + super(t); + } + + public void serialize(Distance distance, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException { + generator.writeStartObject(); + generator.writeFieldName("name"); + generator.writeString(distance.name()); + generator.writeFieldName("unit"); + generator.writeString(distance.getUnit()); + generator.writeFieldName("meters"); + generator.writeNumber(distance.getMeters()); + generator.writeEndObject(); + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumSimple.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumSimple.java new file mode 100644 index 0000000000..a282e9e35f --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumSimple.java @@ -0,0 +1,26 @@ +package com.ossez.jackson.enums.withEnum; + +public enum DistanceEnumSimple { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumSimple(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithJsonFormat.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithJsonFormat.java new file mode 100644 index 0000000000..c3d0050f31 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithJsonFormat.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.enums.withEnum; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum DistanceEnumWithJsonFormat { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumWithJsonFormat(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithValue.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithValue.java new file mode 100644 index 0000000000..a94cdde511 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/DistanceEnumWithValue.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.enums.withEnum; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum DistanceEnumWithValue { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumWithValue(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + @JsonValue + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumCustom.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumCustom.java new file mode 100644 index 0000000000..9895d03262 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumCustom.java @@ -0,0 +1,59 @@ +package com.ossez.jackson.enums.withEnum; + +import com.ossez.jackson.enums.serialization.Distance; + +public class MyDtoWithEnumCustom { + + private String stringValue; + private int intValue; + private boolean booleanValue; + private Distance type; + + public MyDtoWithEnumCustom() { + super(); + } + + public MyDtoWithEnumCustom(final String stringValue, final int intValue, final boolean booleanValue, final Distance type) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + this.type = type; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + public Distance getType() { + return type; + } + + public void setType(final Distance type) { + this.type = type; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumJsonFormat.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumJsonFormat.java new file mode 100644 index 0000000000..c58b20b87d --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/enums/withEnum/MyDtoWithEnumJsonFormat.java @@ -0,0 +1,57 @@ +package com.ossez.jackson.enums.withEnum; + +public class MyDtoWithEnumJsonFormat { + + private String stringValue; + private int intValue; + private boolean booleanValue; + private DistanceEnumWithJsonFormat distanceType; + + public MyDtoWithEnumJsonFormat() { + super(); + } + + public MyDtoWithEnumJsonFormat(final String stringValue, final int intValue, final boolean booleanValue, final DistanceEnumWithJsonFormat type) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + this.distanceType = type; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + public DistanceEnumWithJsonFormat getDistanceType() { + return distanceType; + } + + public void setDistanceType(final DistanceEnumWithJsonFormat type) { + this.distanceType = type; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDto.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDto.java new file mode 100644 index 0000000000..a4583c8b44 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDto.java @@ -0,0 +1,47 @@ +package com.ossez.jackson.field; + +public class MyDto { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDto() { + super(); + } + + public MyDto(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean getBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoAccessLevel.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoAccessLevel.java new file mode 100644 index 0000000000..7c0604990f --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoAccessLevel.java @@ -0,0 +1,23 @@ +package com.ossez.jackson.field; + +public class MyDtoAccessLevel { + + private String stringValue; + int intValue; + protected float floatValue; + public boolean booleanValue; + + public MyDtoAccessLevel() { + super(); + } + + public MyDtoAccessLevel(final String stringValue, final int intValue, final float floatValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.floatValue = floatValue; + this.booleanValue = booleanValue; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithGetter.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithGetter.java new file mode 100644 index 0000000000..7d60251959 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithGetter.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.field; + +public class MyDtoWithGetter { + + private String stringValue; + private int intValue; + + public MyDtoWithGetter() { + super(); + } + + public MyDtoWithGetter(final String stringValue, final int intValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithSetter.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithSetter.java new file mode 100644 index 0000000000..f32c5d2151 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/field/MyDtoWithSetter.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.field; + +public class MyDtoWithSetter { + + private int intValue; + public boolean booleanValue; + + public MyDtoWithSetter() { + super(); + } + + public MyDtoWithSetter(final int intValue, final boolean booleanValue) { + super(); + + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public int accessIntValue() { + return intValue; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Employee.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Employee.java new file mode 100644 index 0000000000..46f44161cd --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Employee.java @@ -0,0 +1,24 @@ +package com.ossez.jackson.immutable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Employee { + + private final long id; + private final String name; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public Employee(@JsonProperty("id") long id, @JsonProperty("name") String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Person.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Person.java new file mode 100644 index 0000000000..9df9f8c808 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/immutable/Person.java @@ -0,0 +1,44 @@ +package com.ossez.jackson.immutable; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; + +@JsonDeserialize(builder = Person.Builder.class) +public class Person { + + private final String name; + private final Integer age; + + private Person(String name, Integer age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public Integer getAge() { + return age; + } + + @JsonPOJOBuilder + static class Builder { + String name; + Integer age; + + Builder withName(String name) { + this.name = name; + return this; + } + + Builder withAge(Integer age) { + this.age = age; + return this; + } + + Person build() { + return new Person(name, age); + } + } +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/ClassWithAMap.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/ClassWithAMap.java new file mode 100644 index 0000000000..09a9818630 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/ClassWithAMap.java @@ -0,0 +1,23 @@ +package com.ossez.jackson.map; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class ClassWithAMap { + + @JsonProperty("map") + @JsonDeserialize(keyUsing = MyPairDeserializer.class) + private final Map map; + + @JsonCreator + public ClassWithAMap(Map map) { + this.map = map; + } + + public Map getMap() { + return map; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPair.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPair.java new file mode 100644 index 0000000000..4578aea4f2 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPair.java @@ -0,0 +1,80 @@ +package com.ossez.jackson.map; + +import com.fasterxml.jackson.annotation.JsonValue; + +public class MyPair { + + private String first; + private String second; + + public MyPair(String first, String second) { + this.first = first; + this.second = second; + } + + public MyPair(String both) { + String[] pairs = both.split("and"); + this.first = pairs[0].trim(); + this.second = pairs[1].trim(); + } + + @Override + @JsonValue + public String toString() { + return first + " and " + second; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((first == null) ? 0 : first.hashCode()); + result = prime * result + ((second == null) ? 0 : second.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof MyPair)) { + return false; + } + MyPair other = (MyPair) obj; + if (first == null) { + if (other.first != null) { + return false; + } + } else if (!first.equals(other.first)) { + return false; + } + if (second == null) { + if (other.second != null) { + return false; + } + } else if (!second.equals(other.second)) { + return false; + } + return true; + } + + public String getFirst() { + return first; + } + + public void setFirst(String first) { + this.first = first; + } + + public String getSecond() { + return second; + } + + public void setSecond(String second) { + this.second = second; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairDeserializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairDeserializer.java new file mode 100644 index 0000000000..5feb836b11 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairDeserializer.java @@ -0,0 +1,16 @@ +package com.ossez.jackson.map; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.KeyDeserializer; + +public class MyPairDeserializer extends KeyDeserializer { + + @Override + public MyPair deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { + + return new MyPair(key); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairSerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairSerializer.java new file mode 100644 index 0000000000..4fe480ff0d --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/map/MyPairSerializer.java @@ -0,0 +1,22 @@ +package com.ossez.jackson.map; + +import java.io.IOException; +import java.io.StringWriter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class MyPairSerializer extends JsonSerializer { + + private final ObjectMapper mapper = new ObjectMapper(); + + @Override + public void serialize(MyPair value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { + StringWriter writer = new StringWriter(); + mapper.writeValue(writer, value); + gen.writeFieldName(writer.toString()); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDto.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDto.java new file mode 100644 index 0000000000..202c4c9aea --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDto.java @@ -0,0 +1,54 @@ +package com.ossez.jackson.mapnull; + +public class MyDto { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDto() { + super(); + } + + public MyDto(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + // + + @Override + public String toString() { + return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]"; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDtoNullKeySerializer.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDtoNullKeySerializer.java new file mode 100644 index 0000000000..299ef45305 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/mapnull/MyDtoNullKeySerializer.java @@ -0,0 +1,27 @@ +package com.ossez.jackson.mapnull; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class MyDtoNullKeySerializer extends StdSerializer { + + private static final long serialVersionUID = -4478531309177369056L; + + public MyDtoNullKeySerializer() { + this(null); + } + + public MyDtoNullKeySerializer(final Class t) { + super(t); + } + + @Override + public void serialize(final Object value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeFieldName(""); + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/tocollection/MyDto.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/tocollection/MyDto.java new file mode 100644 index 0000000000..9b005299f0 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/tocollection/MyDto.java @@ -0,0 +1,54 @@ +package com.ossez.jackson.tocollection; + +public class MyDto { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDto() { + super(); + } + + public MyDto(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + // + + @Override + public String toString() { + return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]"; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/xml/Address.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/xml/Address.java new file mode 100644 index 0000000000..fcf78d025b --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/xml/Address.java @@ -0,0 +1,33 @@ +package com.ossez.jackson.xml; + +public class Address { + + String streetNumber; + String streetName; + String city; + + public String getStreetNumber() { + return streetNumber; + } + + public void setStreetNumber(String streetNumber) { + this.streetNumber = streetNumber; + } + + public String getStreetName() { + return streetName; + } + + public void setStreetName(String streetName) { + this.streetName = streetName; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + +} diff --git a/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/xml/Person.java b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/xml/Person.java new file mode 100644 index 0000000000..08ea503ccc --- /dev/null +++ b/jackson-modules/jackson-conversions/src/main/java/com/ossez/jackson/xml/Person.java @@ -0,0 +1,47 @@ +package com.ossez.jackson.xml; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +import java.util.ArrayList; +import java.util.List; + +@JacksonXmlRootElement(localName = "person") +public final class Person { + private String firstName; + private String lastName; + private List phoneNumbers = new ArrayList<>(); + private List
address = new ArrayList<>(); + + public List
getAddress() { + return address; + } + + public void setAddress(List
address) { + this.address = address; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/date/JacksonDateUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/date/JacksonDateUnitTest.java new file mode 100644 index 0000000000..1171c9e432 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/date/JacksonDateUnitTest.java @@ -0,0 +1,212 @@ +package com.ossez.jackson.date; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.TimeZone; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.util.StdDateFormat; +import com.fasterxml.jackson.datatype.joda.JodaModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +public class JacksonDateUnitTest { + + @Test + public void whenSerializingDateWithJackson_thenSerializedToTimestamp() throws JsonProcessingException, ParseException { + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + + final String toParse = "01-01-1970 01:00"; + final Date date = df.parse(toParse); + final Event event = new Event("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString("3600000")); + } + + @Test + public void whenSerializingDateToISO8601_thenSerializedToText() throws JsonProcessingException, ParseException { + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + + final String toParse = "01-01-1970 02:30"; + final Date date = df.parse(toParse); + final Event event = new Event("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + // StdDateFormat is ISO8601 since jackson 2.9 + mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true)); + + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString("1970-01-01T02:30:00.000+00:00")); + } + + @Test + public void whenDeserialisingZonedDateTimeWithDefaults_thenNotCorrect() + throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); + String converted = objectMapper.writeValueAsString(now); + + ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class); + System.out.println("serialized: " + now); + System.out.println("restored: " + restored); + assertThat(now, is(restored)); + } + + @Test + public void whenSettingObjectMapperDateFormat_thenCorrect() throws JsonProcessingException, ParseException { + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm"); + + final String toParse = "20-12-2014 02:30"; + final Date date = df.parse(toParse); + final Event event = new Event("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(df); + + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString(toParse)); + } + + @Test + public void whenUsingJsonFormatAnnotationToFormatDate_thenCorrect() throws JsonProcessingException, ParseException { + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + + final String toParse = "20-12-2014 02:30:00"; + final Date date = df.parse(toParse); + final EventWithFormat event = new EventWithFormat("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString(toParse)); + } + + @Test + public void whenUsingCustomDateSerializer_thenCorrect() throws JsonProcessingException, ParseException { + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + final String toParse = "20-12-2014 02:30:00"; + final Date date = df.parse(toParse); + final EventWithSerializer event = new EventWithSerializer("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString(toParse)); + } + + @Test + public void whenSerializingJodaTimeWithJackson_thenCorrect() throws JsonProcessingException { + final DateTime date = new DateTime(2014, 12, 20, 2, 30); + final EventWithJodaTime event = new EventWithJodaTime("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString("2014-12-20 02:30")); + } + + @Test + public void whenSerializingJava8DateWithCustomSerializer_thenCorrect() throws JsonProcessingException { + final LocalDateTime date = LocalDateTime.of(2014, 12, 20, 2, 30); + final EventWithLocalDateTime event = new EventWithLocalDateTime("party", date); + + final ObjectMapper mapper = new ObjectMapper(); + final String result = mapper.writeValueAsString(event); + assertThat(result, containsString("2014-12-20 02:30")); + } + + @Test + public void whenDeserializingDateWithJackson_thenCorrect() throws IOException { + final String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}"; + + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + final ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(df); + + final Event event = mapper.readerFor(Event.class) + .readValue(json); + assertEquals("20-12-2014 02:30:00", df.format(event.eventDate)); + } + + @Test + public void whenDeserializingDateUsingCustomDeserializer_thenCorrect() throws IOException { + final String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}"; + + final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + final ObjectMapper mapper = new ObjectMapper(); + + final EventWithSerializer event = mapper.readerFor(EventWithSerializer.class) + .readValue(json); + assertEquals("20-12-2014 02:30:00", df.format(event.eventDate)); + } + + @Test + public void whenSerializingJava8Date_thenCorrect() throws JsonProcessingException { + final LocalDateTime date = LocalDateTime.of(2014, 12, 20, 2, 30); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + final String result = mapper.writeValueAsString(date); + assertThat(result, containsString("2014-12-20T02:30")); + } + + @Test + public void whenSerializingJava8DateAndReadingValue_thenCorrect() throws IOException { + String stringDate = "\"2014-12-20\""; + + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + LocalDate result = mapper.readValue(stringDate, LocalDate.class); + assertThat(result.toString(), containsString("2014-12-20")); + } + + @Test + public void whenSerializingJava8DateAndReadingFromEntity_thenCorrect() throws IOException { + String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014\"}"; + + ObjectMapper mapper = new ObjectMapper(); + + EventWithLocalDate result = mapper.readValue(json, EventWithLocalDate.class); + assertThat(result.getEventDate().toString(), containsString("2014-12-20")); + } + + @Test + public void whenSerializingJodaTime_thenCorrect() throws JsonProcessingException { + final DateTime date = new DateTime(2014, 12, 20, 2, 30, DateTimeZone.forID("Europe/London")); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JodaModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + final String result = mapper.writeValueAsString(date); + assertThat(result, containsString("2014-12-20T02:30:00.000Z")); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/DefaultEnumDeserializationUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/DefaultEnumDeserializationUnitTest.java new file mode 100644 index 0000000000..12596336cc --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/DefaultEnumDeserializationUnitTest.java @@ -0,0 +1,20 @@ +package com.ossez.jackson.enums.deserialization; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; + +import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class DefaultEnumDeserializationUnitTest { + + @Test + public void givenEnum_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException { + String json = "{\"distance\":\"KILOMETER\"}"; + City city = new ObjectMapper().readValue(json, City.class); + + assertEquals(Distance.KILOMETER, city.getDistance()); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/customdeserializer/EnumCustomDeserializationUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/customdeserializer/EnumCustomDeserializationUnitTest.java new file mode 100644 index 0000000000..f3f561e021 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/customdeserializer/EnumCustomDeserializationUnitTest.java @@ -0,0 +1,19 @@ +package com.ossez.jackson.enums.deserialization.customdeserializer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; + +import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EnumCustomDeserializationUnitTest { + + @Test + public void givenEnumWithCustomDeserializer_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException { + String json = "{\"distance\": {\"unit\":\"miles\",\"meters\":1609.34}}"; + + City city = new ObjectMapper().readValue(json, City.class); + assertEquals(Distance.MILE, city.getDistance()); + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsoncreator/EnumDeserializationUsingJsonCreatorUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsoncreator/EnumDeserializationUsingJsonCreatorUnitTest.java new file mode 100644 index 0000000000..239e36b261 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsoncreator/EnumDeserializationUsingJsonCreatorUnitTest.java @@ -0,0 +1,20 @@ +package com.ossez.jackson.enums.deserialization.jsoncreator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; + +import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EnumDeserializationUsingJsonCreatorUnitTest { + + @Test + public void givenEnumWithJsonCreator_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException { + String json = "{\"distance\": {\"unit\":\"miles\",\"meters\":1609.34}}"; + + City city = new ObjectMapper().readValue(json, City.class); + assertEquals(Distance.MILE, city.getDistance()); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsonproperty/EnumDeserializationUsingJsonPropertyUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsonproperty/EnumDeserializationUsingJsonPropertyUnitTest.java new file mode 100644 index 0000000000..883e1d7d57 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsonproperty/EnumDeserializationUsingJsonPropertyUnitTest.java @@ -0,0 +1,21 @@ +package com.ossez.jackson.enums.deserialization.jsonproperty; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; + +import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EnumDeserializationUsingJsonPropertyUnitTest { + + @Test + public void givenEnumWithJsonProperty_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException { + String json = "{\"distance\": \"distance-in-km\"}"; + + City city = new ObjectMapper().readValue(json, City.class); + assertEquals(Distance.KILOMETER, city.getDistance()); + + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsonvalue/EnumDeserializationUsingJsonValueUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsonvalue/EnumDeserializationUsingJsonValueUnitTest.java new file mode 100644 index 0000000000..1b38340684 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/deserialization/jsonvalue/EnumDeserializationUsingJsonValueUnitTest.java @@ -0,0 +1,20 @@ +package com.ossez.jackson.enums.deserialization.jsonvalue; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; + +import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EnumDeserializationUsingJsonValueUnitTest { + + @Test + public void givenEnumWithJsonValue_whenDeserializingJson_thenCorrectRepresentation() throws JsonParseException, IOException { + String json = "{\"distance\": \"0.0254\"}"; + + City city = new ObjectMapper().readValue(json, City.class); + assertEquals(Distance.INCH, city.getDistance()); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/serialization/JacksonEnumSerializationUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/serialization/JacksonEnumSerializationUnitTest.java new file mode 100644 index 0000000000..f3f0440a92 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/serialization/JacksonEnumSerializationUnitTest.java @@ -0,0 +1,20 @@ +package com.ossez.jackson.enums.serialization; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; +import java.io.IOException; + +import org.junit.Test; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonEnumSerializationUnitTest { + + @Test + public final void givenEnum_whenSerializingJson_thenCorrectRepresentation() throws JsonParseException, IOException { + final String dtoAsString = new ObjectMapper().writeValueAsString(Distance.MILE); + + assertThat(dtoAsString, containsString("1609.34")); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/serialization/JacksonSerializationEnumsUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/serialization/JacksonSerializationEnumsUnitTest.java new file mode 100644 index 0000000000..fc9064c3c1 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/enums/serialization/JacksonSerializationEnumsUnitTest.java @@ -0,0 +1,77 @@ +package com.ossez.jackson.enums.serialization; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; + +import org.junit.Test; + +import com.ossez.jackson.enums.withEnum.DistanceEnumSimple; +import com.ossez.jackson.enums.withEnum.DistanceEnumWithJsonFormat; +import com.ossez.jackson.enums.withEnum.DistanceEnumWithValue; +import com.ossez.jackson.enums.withEnum.MyDtoWithEnumCustom; +import com.ossez.jackson.enums.withEnum.MyDtoWithEnumJsonFormat; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonSerializationEnumsUnitTest { + + // tests - simple enum + + @Test + public final void whenSerializingASimpleEnum_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final String enumAsString = mapper.writeValueAsString(DistanceEnumSimple.MILE); + + assertThat(enumAsString, containsString("MILE")); + } + + // tests - enum with main value + + @Test + public final void whenSerializingAEnumWithValue_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final String enumAsString = mapper.writeValueAsString(DistanceEnumWithValue.MILE); + + assertThat(enumAsString, is("1609.34")); + } + + // tests - enum + + @Test + public final void whenSerializingAnEnum_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final String enumAsString = mapper.writeValueAsString(DistanceEnumWithJsonFormat.MILE); + + assertThat(enumAsString, containsString("\"meters\":1609.34")); + } + + @Test + public final void whenSerializingEntityWithEnum_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final String enumAsString = mapper.writeValueAsString(new MyDtoWithEnumJsonFormat("a", 1, true, DistanceEnumWithJsonFormat.MILE)); + + assertThat(enumAsString, containsString("\"meters\":1609.34")); + } + + @Test + public final void whenSerializingArrayOfEnums_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final String json = mapper.writeValueAsString(new DistanceEnumWithJsonFormat[] { DistanceEnumWithJsonFormat.MILE, DistanceEnumWithJsonFormat.KILOMETER }); + + assertThat(json, containsString("\"meters\":1609.34")); + } + + // tests - enum with custom serializer + + @Test + public final void givenCustomSerializer_whenSerializingEntityWithEnum_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final String enumAsString = mapper.writeValueAsString(new MyDtoWithEnumCustom("a", 1, true, Distance.MILE)); + + assertThat(enumAsString, containsString("\"meters\":1609.34")); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/field/JacksonFieldUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/field/JacksonFieldUnitTest.java new file mode 100644 index 0000000000..d3054aa483 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/field/JacksonFieldUnitTest.java @@ -0,0 +1,92 @@ +package com.ossez.jackson.field; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import org.junit.Test; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonFieldUnitTest { + + @Test + public final void givenDifferentAccessLevels_whenPublic_thenSerializable() throws JsonProcessingException { + final ObjectMapper mapper = new ObjectMapper(); + + final MyDtoAccessLevel dtoObject = new MyDtoAccessLevel(); + + final String dtoAsString = mapper.writeValueAsString(dtoObject); + assertThat(dtoAsString, not(containsString("stringValue"))); + assertThat(dtoAsString, not(containsString("intValue"))); + assertThat(dtoAsString, not(containsString("floatValue"))); + assertThat(dtoAsString, containsString("booleanValue")); + System.out.println(dtoAsString); + } + + @Test + public final void givenDifferentAccessLevels_whenGetterAdded_thenSerializable() throws JsonProcessingException { + final ObjectMapper mapper = new ObjectMapper(); + + final MyDtoWithGetter dtoObject = new MyDtoWithGetter(); + + final String dtoAsString = mapper.writeValueAsString(dtoObject); + assertThat(dtoAsString, containsString("stringValue")); + assertThat(dtoAsString, not(containsString("intValue"))); + System.out.println(dtoAsString); + } + + @Test + public final void givenDifferentAccessLevels_whenGetterAdded_thenDeserializable() throws IOException { + final String jsonAsString = "{\"stringValue\":\"dtoString\"}"; + final ObjectMapper mapper = new ObjectMapper(); + + final MyDtoWithGetter dtoObject = mapper.readValue(jsonAsString, MyDtoWithGetter.class); + + assertNotNull(dtoObject); + assertThat(dtoObject.getStringValue(), equalTo("dtoString")); + } + + @Test + public final void givenDifferentAccessLevels_whenSetterAdded_thenDeserializable() throws IOException { + final String jsonAsString = "{\"intValue\":1}"; + final ObjectMapper mapper = new ObjectMapper(); + + final MyDtoWithSetter dtoObject = mapper.readValue(jsonAsString, MyDtoWithSetter.class); + + assertNotNull(dtoObject); + assertThat(dtoObject.accessIntValue(), equalTo(1)); + } + + @Test + public final void givenDifferentAccessLevels_whenSetterAdded_thenStillNotSerializable() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + + final MyDtoWithSetter dtoObject = new MyDtoWithSetter(); + + final String dtoAsString = mapper.writeValueAsString(dtoObject); + assertThat(dtoAsString, not(containsString("intValue"))); + System.out.println(dtoAsString); + } + + @Test + public final void givenDifferentAccessLevels_whenSetVisibility_thenSerializable() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + + final MyDtoAccessLevel dtoObject = new MyDtoAccessLevel(); + + final String dtoAsString = mapper.writeValueAsString(dtoObject); + assertThat(dtoAsString, containsString("stringValue")); + assertThat(dtoAsString, containsString("intValue")); + assertThat(dtoAsString, containsString("booleanValue")); + System.out.println(dtoAsString); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/immutable/ImmutableObjectDeserializationUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/immutable/ImmutableObjectDeserializationUnitTest.java new file mode 100644 index 0000000000..de21167fb0 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/immutable/ImmutableObjectDeserializationUnitTest.java @@ -0,0 +1,38 @@ +package com.ossez.jackson.immutable; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class ImmutableObjectDeserializationUnitTest { + + @Test + public void whenPublicConstructorIsUsed_thenObjectIsDeserialized() throws IOException { + final String json = "{\"name\":\"Frank\",\"id\":5000}"; + Employee employee = new ObjectMapper().readValue(json, Employee.class); + + assertEquals("Frank", employee.getName()); + assertEquals(5000, employee.getId()); + } + + @Test + public void whenBuilderIsUsedAndFieldIsNull_thenObjectIsDeserialized() throws IOException { + final String json = "{\"name\":\"Frank\"}"; + Person person = new ObjectMapper().readValue(json, Person.class); + + assertEquals("Frank", person.getName()); + assertNull(person.getAge()); + } + + @Test + public void whenBuilderIsUsedAndAllFieldsPresent_thenObjectIsDeserialized() throws IOException { + final String json = "{\"name\":\"Frank\",\"age\":50}"; + Person person = new ObjectMapper().readValue(json, Person.class); + + assertEquals("Frank", person.getName()); + assertEquals(50, (int) person.getAge()); + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/map/JacksonMapDeserializeUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/map/JacksonMapDeserializeUnitTest.java new file mode 100644 index 0000000000..dd3db4703d --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/map/JacksonMapDeserializeUnitTest.java @@ -0,0 +1,62 @@ +package com.ossez.jackson.map; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonMapDeserializeUnitTest { + + private Map map; + private Map cmap; + final ObjectMapper mapper = new ObjectMapper(); + + @Test + public void whenSimpleMapDeserialize_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + + final String jsonInput = "{\"key\": \"value\"}"; + TypeReference> typeRef = new TypeReference>() { + }; + + final Map map = mapper.readValue(jsonInput, typeRef); + + Assert.assertEquals("value", map.get("key")); + } + + @Test + public void whenObjectStringMapDeserialize_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + + final String jsonInput = "{\"Abbott and Costello\":\"Comedy\"}"; + + TypeReference> typeRef = new TypeReference>() { + }; + + map = mapper.readValue(jsonInput, typeRef); + + Assert.assertEquals("Comedy", map.get(new MyPair("Abbott", "Costello"))); + + ClassWithAMap classWithMap = mapper.readValue(jsonInput, ClassWithAMap.class); + + Assert.assertEquals("Comedy", classWithMap.getMap() + .get(new MyPair("Abbott", "Costello"))); + } + + @Test + public void whenObjectObjectMapDeserialize_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + + final String jsonInput = "{\"Abbott and Costello\" : \"Comedy and 1940s\"}"; + TypeReference> typeRef = new TypeReference>() { + }; + + cmap = mapper.readValue(jsonInput, typeRef); + + Assert.assertEquals(new MyPair("Comedy", "1940s"), cmap.get(new MyPair("Abbott", "Costello"))); + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/map/JacksonMapSerializeUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/map/JacksonMapSerializeUnitTest.java new file mode 100644 index 0000000000..af8bcfb083 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/map/JacksonMapSerializeUnitTest.java @@ -0,0 +1,65 @@ +package com.ossez.jackson.map; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.MapSerializer; + +public class JacksonMapSerializeUnitTest { + + @JsonSerialize(keyUsing = MyPairSerializer.class) + private Map map; + + @JsonSerialize(keyUsing = MapSerializer.class) + private Map cmap; + + @JsonSerialize(keyUsing = MyPairSerializer.class) + private MyPair mapKey; + + @JsonSerialize(keyUsing = MyPairSerializer.class) + private MyPair mapValue; + + final ObjectMapper mapper = new ObjectMapper(); + + @Test + public void whenSimpleMapSerialize_thenCorrect() throws JsonProcessingException { + + Map map = new HashMap<>(); + map.put("key", "value"); + + final String jsonResult = mapper.writeValueAsString(map); + + Assert.assertEquals("{\"key\":\"value\"}", jsonResult); + } + + @Test + public void whenCustomObjectStringMapSerialize_thenCorrect() throws JsonProcessingException { + + map = new HashMap<>(); + MyPair key = new MyPair("Abbott", "Costello"); + map.put(key, "Comedy"); + + final String jsonResult = mapper.writeValueAsString(map); + + Assert.assertEquals("{\"Abbott and Costello\":\"Comedy\"}", jsonResult); + } + + @Test + public void whenCustomObjectObjectMapSerialize_thenCorrect() throws JsonProcessingException { + + cmap = new HashMap<>(); + mapKey = new MyPair("Abbott", "Costello"); + mapValue = new MyPair("Comedy", "1940's"); + cmap.put(mapKey, mapValue); + + final String jsonResult = mapper.writeValueAsString(cmap); + + Assert.assertEquals("{\"Abbott and Costello\":\"Comedy and 1940's\"}", jsonResult); + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/mapnull/JacksonMapNullUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/mapnull/JacksonMapNullUnitTest.java new file mode 100644 index 0000000000..3d65b2397b --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/mapnull/JacksonMapNullUnitTest.java @@ -0,0 +1,99 @@ +package com.ossez.jackson.mapnull; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; + +public class JacksonMapNullUnitTest { + + @Test + public final void givenIgnoringMapNullValue_whenWritingMapObjectWithNullValue_thenIgnored() throws JsonProcessingException { + final ObjectMapper mapper = new ObjectMapper(); + // mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); + mapper.setSerializationInclusion(Include.NON_NULL); + + final MyDto dtoObject1 = new MyDto(); + + final Map dtoMap = new HashMap(); + dtoMap.put("dtoObject1", dtoObject1); + dtoMap.put("dtoObject2", null); + + final String dtoMapAsString = mapper.writeValueAsString(dtoMap); + + assertThat(dtoMapAsString, containsString("dtoObject1")); + assertThat(dtoMapAsString, not(containsString("dtoObject2"))); + System.out.println(dtoMapAsString); + } + + @Test + public final void givenIgnoringMapValueObjectWithNullField_whenWritingMapValueObjectWithNullField_thenIgnored() throws JsonProcessingException { + final ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(Include.NON_NULL); + + final MyDto dtoObject = new MyDto(); + + final Map dtoMap = new HashMap(); + dtoMap.put("dtoObject", dtoObject); + + final String dtoMapAsString = mapper.writeValueAsString(dtoMap); + + assertThat(dtoMapAsString, containsString("dtoObject")); + assertThat(dtoMapAsString, not(containsString("stringValue"))); + System.out.println(dtoMapAsString); + } + + @Test + public final void givenAllowingMapObjectWithNullKey_whenWriting_thenCorrect() throws JsonProcessingException { + final ObjectMapper mapper = new ObjectMapper(); + mapper.getSerializerProvider() + .setNullKeySerializer(new MyDtoNullKeySerializer()); + + final MyDto dtoObject1 = new MyDto(); + dtoObject1.setStringValue("dtoObjectString1"); + final MyDto dtoObject2 = new MyDto(); + dtoObject2.setStringValue("dtoObjectString2"); + + final Map dtoMap = new HashMap(); + dtoMap.put(null, dtoObject1); + dtoMap.put("obj2", dtoObject2); + + final String dtoMapAsString = mapper.writeValueAsString(dtoMap); + + System.out.println(dtoMapAsString); + assertThat(dtoMapAsString, containsString("\"\"")); + assertThat(dtoMapAsString, containsString("dtoObjectString1")); + assertThat(dtoMapAsString, containsString("obj2")); + } + + @Test + public final void givenAllowingMapObjectOneNullKey_whenWritingMapObjectWithTwoNullKeys_thenOverride() throws JsonProcessingException { + final ObjectMapper mapper = new ObjectMapper(); + mapper.getSerializerProvider() + .setNullKeySerializer(new MyDtoNullKeySerializer()); + + final MyDto dtoObject1 = new MyDto(); + dtoObject1.setStringValue("dtoObject1String"); + + final MyDto dtoObject2 = new MyDto(); + dtoObject2.setStringValue("dtoObject2String"); + + final Map dtoMap = new HashMap(); + dtoMap.put(null, dtoObject1); + dtoMap.put(null, dtoObject2); + + final String dtoMapAsString = mapper.writeValueAsString(dtoMap); + + assertThat(dtoMapAsString, not(containsString("dtoObject1String"))); + assertThat(dtoMapAsString, containsString("dtoObject2String")); + System.out.println(dtoMapAsString); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/DeserializeWithNestedPropertiesUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/DeserializeWithNestedPropertiesUnitTest.java new file mode 100644 index 0000000000..e6b6e0b8d7 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/DeserializeWithNestedPropertiesUnitTest.java @@ -0,0 +1,70 @@ +package com.ossez.jackson.nested; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class DeserializeWithNestedPropertiesUnitTest { + + private String SOURCE_JSON = "{\"id\":\"957c43f2-fa2e-42f9-bf75-6e3d5bb6960a\",\"name\":\"The Best Product\",\"brand\":{\"id\":\"9bcd817d-0141-42e6-8f04-e5aaab0980b6\",\"name\":\"ACME Products\",\"owner\":{\"id\":\"b21a80b1-0c09-4be3-9ebd-ea3653511c13\",\"name\":\"Ultimate Corp, Inc.\"}}}"; + + @Test + public void whenUsingAnnotations_thenOk() throws IOException { + Product product = new ObjectMapper().readerFor(Product.class) + .readValue(SOURCE_JSON); + + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } + + @Test + public void whenUsingJsonNode_thenOk() throws IOException { + JsonNode productNode = new ObjectMapper().readTree(SOURCE_JSON); + + Product product = new Product(); + product.setId(productNode.get("id") + .textValue()); + product.setName(productNode.get("name") + .textValue()); + product.setBrandName(productNode.get("brand") + .get("name") + .textValue()); + product.setOwnerName(productNode.get("brand") + .get("owner") + .get("name") + .textValue()); + + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } + + @Test + public void whenUsingDeserializerManuallyRegistered_thenOk() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + module.addDeserializer(Product.class, new ProductDeserializer()); + mapper.registerModule(module); + + Product product = mapper.readValue(SOURCE_JSON, Product.class); + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } + + @Test + public void whenUsingDeserializerAutoRegistered_thenOk() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + Product product = mapper.readValue(SOURCE_JSON, Product.class); + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/Product.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/Product.java new file mode 100644 index 0000000000..07c21e71ba --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/Product.java @@ -0,0 +1,55 @@ +package com.ossez.jackson.nested; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = ProductDeserializer.class) +public class Product { + + private String id; + private String name; + private String brandName; + private String ownerName; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getBrandName() { + return brandName; + } + + public void setBrandName(String brandName) { + this.brandName = brandName; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + @SuppressWarnings("unchecked") + @JsonProperty("brand") + private void unpackNested(Map brand) { + this.brandName = (String) brand.get("name"); + Map owner = (Map) brand.get("owner"); + this.ownerName = owner.get("name"); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/ProductDeserializer.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/ProductDeserializer.java new file mode 100644 index 0000000000..e25c254d47 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/nested/ProductDeserializer.java @@ -0,0 +1,40 @@ +package com.ossez.jackson.nested; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +@SuppressWarnings("serial") +public class ProductDeserializer extends StdDeserializer { + + public ProductDeserializer() { + this(null); + } + + public ProductDeserializer(Class vc) { + super(vc); + } + + @Override + public Product deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode productNode = jp.getCodec() + .readTree(jp); + Product product = new Product(); + product.setId(productNode.get("id") + .textValue()); + product.setName(productNode.get("name") + .textValue()); + product.setBrandName(productNode.get("brand") + .get("name") + .textValue()); + product.setOwnerName(productNode.get("brand") + .get("owner") + .get("name") + .textValue()); + return product; + } +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/tocollection/JacksonCollectionDeserializationUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/tocollection/JacksonCollectionDeserializationUnitTest.java new file mode 100644 index 0000000000..f0f22b4533 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/tocollection/JacksonCollectionDeserializationUnitTest.java @@ -0,0 +1,75 @@ +package com.ossez.jackson.tocollection; + +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; +import com.google.common.collect.Lists; + +public class JacksonCollectionDeserializationUnitTest { + + // tests - json to multiple entity + + @Test + public final void givenJsonArray_whenDeserializingAsArray_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + + final List listOfDtos = Lists.newArrayList(new MyDto("a", 1, true), new MyDto("bc", 3, false)); + listOfDtos + final String jsonArray = mapper.writeValueAsString(listOfDtos); + // [{"stringValue":"a","intValue":1,"booleanValue":true},{"stringValue":"bc","intValue":3,"booleanValue":false}] + + final MyDto[] asArray = mapper.readValue(jsonArray, MyDto[].class); + assertThat(asArray[0], instanceOf(MyDto.class)); + } + + @Test + public final void givenJsonArray_whenDeserializingAsListWithNoTypeInfo_thenNotCorrect() throws JsonParseException, JsonMappingException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + + final List listOfDtos = Lists.newArrayList(new MyDto("a", 1, true), new MyDto("bc", 3, false)); + final String jsonArray = mapper.writeValueAsString(listOfDtos); + // [{"stringValue":"a","intValue":1,"booleanValue":true},{"stringValue":"bc","intValue":3,"booleanValue":false}] + + final List asList = mapper.readValue(jsonArray, List.class); + assertThat((Object) asList.get(0), instanceOf(LinkedHashMap.class)); + } + + @Test + public final void givenJsonArray_whenDeserializingAsListWithTypeReferenceHelp_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + + final List listOfDtos = Lists.newArrayList(new MyDto("a", 1, true), new MyDto("bc", 3, false)); + final String jsonArray = mapper.writeValueAsString(listOfDtos); + // [{"stringValue":"a","intValue":1,"booleanValue":true},{"stringValue":"bc","intValue":3,"booleanValue":false}] + + final List asList = mapper.readValue(jsonArray, new TypeReference>() { + }); + assertThat(asList.get(0), instanceOf(MyDto.class)); + } + + @Test + public final void givenJsonArray_whenDeserializingAsListWithJavaTypeHelp_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + + final List listOfDtos = Lists.newArrayList(new MyDto("a", 1, true), new MyDto("bc", 3, false)); + final String jsonArray = mapper.writeValueAsString(listOfDtos); + // [{"stringValue":"a","intValue":1,"booleanValue":true},{"stringValue":"bc","intValue":3,"booleanValue":false}] + + final CollectionType javaType = mapper.getTypeFactory() + .constructCollectionType(List.class, MyDto.class); + final List asList = mapper.readValue(jsonArray, javaType); + assertThat(asList.get(0), instanceOf(MyDto.class)); + } + +} +// a (private) no-args constructor is required (simulate without) diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/tojsonnode/StringToJsonNodeUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/tojsonnode/StringToJsonNodeUnitTest.java new file mode 100644 index 0000000000..9cc438c259 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/tojsonnode/StringToJsonNodeUnitTest.java @@ -0,0 +1,51 @@ +package com.ossez.jackson.tojsonnode; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import org.junit.Test; + +import java.io.IOException; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class StringToJsonNodeUnitTest { + + @Test + public final void whenParsingJsonStringIntoJsonNode_thenCorrect() throws JsonParseException, IOException { + final String jsonString = "{\"k1\":\"v1\",\"k2\":\"v2\"}"; + + final ObjectMapper mapper = new ObjectMapper(); + final JsonNode actualObj = mapper.readTree(jsonString); + + assertNotNull(actualObj); + } + + @Test + public final void givenUsingLowLevelDetails_whenParsingJsonStringIntoJsonNode_thenCorrect() throws JsonParseException, IOException { + final String jsonString = "{\"k1\":\"v1\",\"k2\":\"v2\"}"; + + final ObjectMapper mapper = new ObjectMapper(); + final JsonFactory factory = mapper.getFactory(); + final JsonParser parser = factory.createParser(jsonString); + final JsonNode actualObj = mapper.readTree(parser); + + assertNotNull(actualObj); + } + + @Test + public final void givenTheJsonNode_whenRetrievingDataFromId_thenCorrect() throws JsonParseException, IOException { + final String jsonString = "{\"k1\":\"v1\",\"k2\":\"v2\"}"; + final ObjectMapper mapper = new ObjectMapper(); + final JsonNode actualObj = mapper.readTree(jsonString); + + // When + final JsonNode jsonNode1 = actualObj.get("k1"); + assertThat(jsonNode1.textValue(), equalTo("v1")); + } + +} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/xml/XMLSerializeDeserializeUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/xml/XMLSerializeDeserializeUnitTest.java new file mode 100644 index 0000000000..e4d879a319 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/java/com/ossez/jackson/xml/XMLSerializeDeserializeUnitTest.java @@ -0,0 +1,182 @@ +package com.ossez.jackson.xml; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +public class XMLSerializeDeserializeUnitTest { + + @Test + public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException { + XmlMapper xmlMapper = new XmlMapper(); + String xml = xmlMapper.writeValueAsString(new SimpleBean()); + assertNotNull(xml); + } + + @Test + public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + xmlMapper.writeValue(new File("target/simple_bean.xml"), new SimpleBean()); + File file = new File("target/simple_bean.xml"); + assertNotNull(file); + } + + @Test + public void whenJavaGotFromXmlStr_thenCorrect() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + SimpleBean value = xmlMapper.readValue("12", SimpleBean.class); + assertTrue(value.getX() == 1 && value.getY() == 2); + } + + @Test + public void whenJavaGotFromXmlFile_thenCorrect() throws IOException { + File file = new File("src/test/resources/simple_bean.xml"); + XmlMapper xmlMapper = new XmlMapper(); + String xml = inputStreamToString(new FileInputStream(file)); + SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class); + assertTrue(value.getX() == 1 && value.getY() == 2); + } + + @Test + public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + SimpleBeanForCapitalizedFields value = xmlMapper.readValue("12", SimpleBeanForCapitalizedFields.class); + assertTrue(value.getX() == 1 && value.getY() == 2); + } + + @Test + public void whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"), new SimpleBeanForCapitalizedFields()); + File file = new File("target/simple_bean_capitalized.xml"); + assertNotNull(file); + } + + @Test + public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + + String xml = "RohanDaye99110347319911033478
1Name1City1
2Name2City2
"; + Person value = xmlMapper.readValue(xml, Person.class); + + assertTrue(value.getAddress() + .get(0) + .getCity() + .equalsIgnoreCase("city1") + && value.getAddress() + .get(1) + .getCity() + .equalsIgnoreCase("city2")); + } + + @Test + public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + + String expectedXml = "RohanDaye99110347319911033478
1Name1City1
2Name2City2
"; + + Person person = new Person(); + + person.setFirstName("Rohan"); + person.setLastName("Daye"); + + List ph = new ArrayList<>(); + ph.add("9911034731"); + ph.add("9911033478"); + person.setPhoneNumbers(ph); + + List
addresses = new ArrayList<>(); + + Address address1 = new Address(); + address1.setStreetNumber("1"); + address1.setStreetName("Name1"); + address1.setCity("City1"); + + Address address2 = new Address(); + address2.setStreetNumber("2"); + address2.setStreetName("Name2"); + address2.setCity("City2"); + + addresses.add(address1); + addresses.add(address2); + + person.setAddress(addresses); + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + xmlMapper.writeValue(byteArrayOutputStream, person); + assertEquals(expectedXml, byteArrayOutputStream.toString()); + } + + private static String inputStreamToString(InputStream is) throws IOException { + BufferedReader br; + StringBuilder sb = new StringBuilder(); + + String line; + br = new BufferedReader(new InputStreamReader(is)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + br.close(); + return sb.toString(); + } +} + +class SimpleBean { + private int x = 1; + private int y = 2; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + +} + +class SimpleBeanForCapitalizedFields { + @JsonProperty("X") + private int x = 1; + private int y = 2; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/test/resources/simple_bean.xml b/jackson-modules/jackson-conversions/src/test/resources/simple_bean.xml new file mode 100644 index 0000000000..7829ea35a4 --- /dev/null +++ b/jackson-modules/jackson-conversions/src/test/resources/simple_bean.xml @@ -0,0 +1,4 @@ + + 1 + 2 + \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/File.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/File.java new file mode 100644 index 0000000000..791ad3a466 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/File.java @@ -0,0 +1,25 @@ +package com.baeldung.defaultserializercustomserializer; + +public class File { + + private Long id; + + private String name; + + public Long getId() { + return id; + } + + public void setId(Long 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-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/Folder.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/Folder.java new file mode 100644 index 0000000000..6f423059a2 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/Folder.java @@ -0,0 +1,82 @@ +package com.baeldung.defaultserializercustomserializer; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class Folder { + + private Long id; + + private String name; + + private String owner; + + private Date created; + + private Date modified; + + private Date lastAccess; + + @JsonIgnore + private List files = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getModified() { + return modified; + } + + public void setModified(Date modified) { + this.modified = modified; + } + + public Date getLastAccess() { + return lastAccess; + } + + public void setLastAccess(Date lastAccess) { + this.lastAccess = lastAccess; + } + + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderBeanSerializerModifier.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderBeanSerializerModifier.java new file mode 100644 index 0000000000..819971939c --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderBeanSerializerModifier.java @@ -0,0 +1,20 @@ +package com.baeldung.defaultserializercustomserializer; + +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; + +public class FolderBeanSerializerModifier extends BeanSerializerModifier { + + @Override + public JsonSerializer modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer serializer) { + + if (beanDesc.getBeanClass().equals(Folder.class)) { + return new FolderSerializerWithDefaultSerializerStored((JsonSerializer) serializer); + } + + return serializer; + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializer.java new file mode 100644 index 0000000000..3869ab15d8 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializer.java @@ -0,0 +1,34 @@ +package com.baeldung.defaultserializercustomserializer; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializer extends StdSerializer { + + public FolderSerializer() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + gen.writeArrayFieldStart("files"); + for (File file : value.getFiles()) { + gen.writeStartObject(); + gen.writeNumberField("id", file.getId()); + gen.writeStringField("name", file.getName()); + gen.writeEndObject(); + } + gen.writeEndArray(); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-modules/jackson/README.md b/jackson-modules/jackson/README.md new file mode 100644 index 0000000000..5fa0e1e7d9 --- /dev/null +++ b/jackson-modules/jackson/README.md @@ -0,0 +1,14 @@ +## Jackson 相关文章和实例 + +这个模块主要是针对 Jackson 有关的文章 + +### 相关课程和讨论 + +有关 "计算机设计相关的课程" :https://www.ossez.com/ + +### 相关文章 +- [Using Optional with Jackson](https://www.baeldung.com/jackson-optional) +- [Compare Two JSON Objects with Jackson](https://www.baeldung.com/jackson-compare-two-json-objects) +- [Jackson vs Gson](https://www.baeldung.com/jackson-vs-gson) +- [Inheritance with Jackson](https://www.baeldung.com/jackson-inheritance) +- [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model) diff --git a/jackson-modules/jackson/pom.xml b/jackson-modules/jackson/pom.xml new file mode 100644 index 0000000000..fdf0c30749 --- /dev/null +++ b/jackson-modules/jackson/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + jackson + 0.0.1-SNAPSHOT + jackson + + + com.ossez + jackson-modules + 0.0.2-SNAPSHOT + + + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson.version} + + + com.fasterxml.jackson.module + jackson-module-jsonSchema + ${jackson.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + ${jackson.version} + + + + io.rest-assured + json-schema-validator + ${rest-assured.version} + test + + + io.rest-assured + json-path + ${rest-assured.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + jackson + + + src/main/resources + true + + + + + + + + + \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jacksoninject/Person.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jacksoninject/Person.java new file mode 100644 index 0000000000..154d994b12 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jacksoninject/Person.java @@ -0,0 +1,43 @@ +package com.ossez.jackson.deserialization.jacksoninject; + +import com.fasterxml.jackson.annotation.JacksonInject; + +import java.util.UUID; + +public class Person { + + @JacksonInject + private UUID id; + private String firstName; + private String lastName; + + public Person() { + + } + + public Person(String firstName, String lastName) { + this.id = UUID.randomUUID(); + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public UUID getId() { + return id; + } +} diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsonanysetter/Inventory.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsonanysetter/Inventory.java new file mode 100644 index 0000000000..390da8a2e2 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsonanysetter/Inventory.java @@ -0,0 +1,20 @@ +package com.ossez.jackson.deserialization.jsonanysetter; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonAnySetter; + +public class Inventory { + + private Map countryDeliveryCost = new HashMap<>(); + + public Map getCountryDeliveryCost() { + return countryDeliveryCost; + } + + @JsonAnySetter + public void addCountryDeliveryCost(String country, Float cost) { + countryDeliveryCost.put(country, cost); + } +} diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsondeserialize/Book.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsondeserialize/Book.java new file mode 100644 index 0000000000..4d47d79d7b --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsondeserialize/Book.java @@ -0,0 +1,75 @@ +package com.ossez.jackson.deserialization.jsondeserialize; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.UUID; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class Book { + + private UUID id; + private String title; + private float price; + private String ISBN; + + @JsonDeserialize(using = CustomDateDeserializer.class) + private Date published; + private BigDecimal pages; + + public Book() { + } + + public Book(String title) { + this.id = UUID.randomUUID(); + this.title = title; + } + + public String getISBN() { + return ISBN; + } + + public void setISBN(String ISBN) { + this.ISBN = ISBN; + } + + public Date getPublished() { + return published; + } + + public void setPublished(Date published) { + this.published = published; + } + + public BigDecimal getPages() { + return pages; + } + + public void setPages(BigDecimal pages) { + this.pages = pages; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public float getPrice() { + return price; + } + + public void setPrice(float price) { + this.price = price; + } +} diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsondeserialize/CustomDateDeserializer.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsondeserialize/CustomDateDeserializer.java new file mode 100644 index 0000000000..762d198457 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/deserialization/jsondeserialize/CustomDateDeserializer.java @@ -0,0 +1,33 @@ +package com.ossez.jackson.deserialization.jsondeserialize; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class CustomDateDeserializer extends StdDeserializer { + + private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); + + public CustomDateDeserializer() { + this(null); + } + + public CustomDateDeserializer(Class vc) { + super(vc); + } + + @Override + public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException { + String date = jsonparser.getText(); + try { + return formatter.parse(date); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } +} diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/domain/Person.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/domain/Person.java new file mode 100644 index 0000000000..026d52cfaa --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/domain/Person.java @@ -0,0 +1,30 @@ +package com.ossez.jackson.domain; + +public class Person { + + private String firstName; + private String lastName; + + public Person(String firstName, String lastName) { + super(); + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} + diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/Event.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/Event.java new file mode 100644 index 0000000000..8843bcc287 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/Event.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.inheritance; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "eventType") +abstract public class Event { + private final String id; + private final Long timestamp; + + @JsonCreator + public Event(@JsonProperty("id") String id, @JsonProperty("timestamp") Long timestamp) { + this.id = id; + this.timestamp = timestamp; + } + + public Long getTimestamp() { + return timestamp; + } + + public String getId() { + return id; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/IgnoranceAnnotationStructure.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/IgnoranceAnnotationStructure.java new file mode 100644 index 0000000000..87cab760ce --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/IgnoranceAnnotationStructure.java @@ -0,0 +1,96 @@ +package com.ossez.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-modules/jackson/src/main/java/com/ossez/jackson/inheritance/IgnoranceMixinOrIntrospection.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/IgnoranceMixinOrIntrospection.java new file mode 100644 index 0000000000..aa352d79a0 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/IgnoranceMixinOrIntrospection.java @@ -0,0 +1,91 @@ +package com.ossez.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-modules/jackson/src/main/java/com/ossez/jackson/inheritance/ItemIdAddedToUser.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/ItemIdAddedToUser.java new file mode 100644 index 0000000000..1a5afa72b1 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/ItemIdAddedToUser.java @@ -0,0 +1,28 @@ +package com.ossez.jackson.inheritance; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeName("itemIdAddedToUser") +@JsonIgnoreProperties("id") +public class ItemIdAddedToUser extends Event { + private final String itemId; + private final Long quantity; + + @JsonCreator + public ItemIdAddedToUser(@JsonProperty("id") String id, @JsonProperty("timestamp") Long timestamp, @JsonProperty("itemId") String itemId, @JsonProperty("quantity") Long quantity) { + super(id, timestamp); + this.itemId = itemId; + this.quantity = quantity; + } + + public String getItemId() { + return itemId; + } + + public Long getQuantity() { + return quantity; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/ItemIdRemovedFromUser.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/ItemIdRemovedFromUser.java new file mode 100644 index 0000000000..88e2c7968f --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/ItemIdRemovedFromUser.java @@ -0,0 +1,26 @@ +package com.ossez.jackson.inheritance; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeName("itemIdRemovedFromUser") +public class ItemIdRemovedFromUser extends Event { + private final String itemId; + private final Long quantity; + + @JsonCreator + public ItemIdRemovedFromUser(@JsonProperty("id") String id, @JsonProperty("timestamp") Long timestamp, @JsonProperty("itemId") String itemId, @JsonProperty("quantity") Long quantity) { + super(id, timestamp); + this.itemId = itemId; + this.quantity = quantity; + } + + public String getItemId() { + return itemId; + } + + public Long getQuantity() { + return quantity; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/SubTypeConstructorStructure.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/SubTypeConstructorStructure.java new file mode 100644 index 0000000000..afca1443de --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/SubTypeConstructorStructure.java @@ -0,0 +1,92 @@ +package com.ossez.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-modules/jackson/src/main/java/com/ossez/jackson/inheritance/SubTypeConversionStructure.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/SubTypeConversionStructure.java new file mode 100644 index 0000000000..006fc79111 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/SubTypeConversionStructure.java @@ -0,0 +1,87 @@ +package com.ossez.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-modules/jackson/src/main/java/com/ossez/jackson/inheritance/TypeInfoAnnotatedStructure.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/TypeInfoAnnotatedStructure.java new file mode 100644 index 0000000000..b9b730f49f --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/TypeInfoAnnotatedStructure.java @@ -0,0 +1,102 @@ +package com.ossez.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-modules/jackson/src/main/java/com/ossez/jackson/inheritance/TypeInfoStructure.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/TypeInfoStructure.java new file mode 100644 index 0000000000..d2af497313 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/inheritance/TypeInfoStructure.java @@ -0,0 +1,96 @@ +package com.ossez.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-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/ActorJackson.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/ActorJackson.java new file mode 100644 index 0000000000..4338159b18 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/ActorJackson.java @@ -0,0 +1,61 @@ +package com.ossez.jackson.jacksonvsgson; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +public class ActorJackson { + + private String imdbId; + private Date dateOfBirth; + private List filmography; + + public ActorJackson() { + super(); + } + + public ActorJackson(String imdbId, Date dateOfBirth, List filmography) { + super(); + this.imdbId = imdbId; + this.dateOfBirth = dateOfBirth; + this.filmography = filmography; + } + + @Override + public String toString() { + return "ActorJackson [imdbId=" + imdbId + ", dateOfBirth=" + formatDateOfBirth() + ", filmography=" + filmography + "]"; + } + + public String getImdbId() { + return imdbId; + } + + public void setImdbId(String imdbId) { + this.imdbId = imdbId; + } + + public Date getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(Date dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public List getFilmography() { + return filmography; + } + + public void setFilmography(List filmography) { + this.filmography = filmography; + } + + private String formatDateOfBirth() { + final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.US); + formatter.setTimeZone(TimeZone.getTimeZone("GMT")); + return formatter.format(dateOfBirth); + } +} diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/ActorJacksonSerializer.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/ActorJacksonSerializer.java new file mode 100644 index 0000000000..bb67092bd9 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/ActorJacksonSerializer.java @@ -0,0 +1,32 @@ +package com.ossez.jackson.jacksonvsgson; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class ActorJacksonSerializer extends StdSerializer { + + private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + public ActorJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize(ActorJackson actor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("imdbId", actor.getImdbId()); + jsonGenerator.writeObjectField("dateOfBirth", actor.getDateOfBirth() != null ? sdf.format(actor.getDateOfBirth()) : null); + jsonGenerator.writeNumberField("N° Film: ", actor.getFilmography() != null ? actor.getFilmography() + .size() : null); + jsonGenerator.writeStringField("filmography", actor.getFilmography() + .stream() + .collect(Collectors.joining("-"))); + jsonGenerator.writeEndObject(); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/Movie.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/Movie.java new file mode 100644 index 0000000000..6d0feb0a32 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/Movie.java @@ -0,0 +1,50 @@ +package com.ossez.jackson.jacksonvsgson; + +import java.util.List; + +public class Movie { + + private String imdbId; + private String director; + private List actors; + + public Movie(String imdbId, String director, List actors) { + super(); + this.imdbId = imdbId; + this.director = director; + this.actors = actors; + } + + public Movie() { + super(); + } + + @Override + public String toString() { + return "Movie [imdbId=" + imdbId + ", director=" + director + ", actors=" + actors + "]"; + } + + public String getImdbId() { + return imdbId; + } + + public void setImdbId(String imdbId) { + this.imdbId = imdbId; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public List getActors() { + return actors; + } + + public void setActors(List actors) { + this.actors = actors; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/MovieWithNullValue.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/MovieWithNullValue.java new file mode 100644 index 0000000000..2f6dceb6fe --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/jacksonvsgson/MovieWithNullValue.java @@ -0,0 +1,46 @@ +package com.ossez.jackson.jacksonvsgson; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.util.List; + +public class MovieWithNullValue { + + private String imdbId; + + @JsonIgnore + private String director; + + private List actors; + + public MovieWithNullValue(String imdbID, String director, List actors) { + super(); + this.imdbId = imdbID; + this.director = director; + this.actors = actors; + } + + public String getImdbID() { + return imdbId; + } + + public void setImdbID(String imdbID) { + this.imdbId = imdbID; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public List getActors() { + return actors; + } + + public void setActors(List actors) { + this.actors = actors; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/node/JsonNodeIterator.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/node/JsonNodeIterator.java new file mode 100644 index 0000000000..a368e0adb0 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/node/JsonNodeIterator.java @@ -0,0 +1,62 @@ +package com.ossez.jackson.node; + +import java.util.Iterator; +import java.util.Map.Entry; + +import com.fasterxml.jackson.databind.JsonNode; + +public class JsonNodeIterator { + + private static final String NEW_LINE = "\n"; + private static final String FIELD_DELIMITER = ": "; + private static final String ARRAY_PREFIX = "- "; + private static final String YAML_PREFIX = " "; + + public String toYaml(JsonNode root) { + StringBuilder yaml = new StringBuilder(); + processNode(root, yaml, 0); + return yaml.toString(); + } + + private void processNode(JsonNode jsonNode, StringBuilder yaml, int depth) { + if (jsonNode.isValueNode()) { + yaml.append(jsonNode.asText()); + } + else if (jsonNode.isArray()) { + for (JsonNode arrayItem : jsonNode) { + appendNodeToYaml(arrayItem, yaml, depth, true); + } + } + else if (jsonNode.isObject()) { + appendNodeToYaml(jsonNode, yaml, depth, false); + } + } + + private void appendNodeToYaml(JsonNode node, StringBuilder yaml, int depth, boolean isArrayItem) { + Iterator> fields = node.fields(); + boolean isFirst = true; + while (fields.hasNext()) { + Entry jsonField = fields.next(); + addFieldNameToYaml(yaml, jsonField.getKey(), depth, isArrayItem && isFirst); + processNode(jsonField.getValue(), yaml, depth+1); + isFirst = false; + } + + } + + private void addFieldNameToYaml(StringBuilder yaml, String fieldName, int depth, boolean isFirstInArray) { + if (yaml.length()>0) { + yaml.append(NEW_LINE); + int requiredDepth = (isFirstInArray) ? depth-1 : depth; + for(int i = 0; i < requiredDepth; i++) { + yaml.append(YAML_PREFIX); + } + if (isFirstInArray) { + yaml.append(ARRAY_PREFIX); + } + } + yaml.append(fieldName); + yaml.append(FIELD_DELIMITER); + } + +} diff --git a/jackson-modules/jackson/src/main/java/com/ossez/jackson/optionalwithjackson/Book.java b/jackson-modules/jackson/src/main/java/com/ossez/jackson/optionalwithjackson/Book.java new file mode 100644 index 0000000000..aeda5c9b92 --- /dev/null +++ b/jackson-modules/jackson/src/main/java/com/ossez/jackson/optionalwithjackson/Book.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.optionalwithjackson; + +import java.util.Optional; + +public class Book { + + private String title; + private Optional subTitle; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Optional getSubTitle() { + return subTitle; + } + + public void setSubTitle(Optional subTitle) { + this.subTitle = subTitle; + } +} diff --git a/jackson-modules/jackson/src/main/resources/example1.json b/jackson-modules/jackson/src/main/resources/example1.json new file mode 100644 index 0000000000..46d2982cec --- /dev/null +++ b/jackson-modules/jackson/src/main/resources/example1.json @@ -0,0 +1,12 @@ +{ + "collection": [ + { + "name": "Test order1", + "detail": "ahk ks" + }, + { + "name": "Test order2", + "detail": "Fisteku" + } + ] +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/resources/example2.json b/jackson-modules/jackson/src/main/resources/example2.json new file mode 100644 index 0000000000..f4433731e6 --- /dev/null +++ b/jackson-modules/jackson/src/main/resources/example2.json @@ -0,0 +1,10 @@ +[ + { + "name": "Test order1", + "detail": "ahk ks" + }, + { + "name": "Test order2", + "detail": "Fisteku" + } +] \ No newline at end of file diff --git a/jackson-modules/jackson/src/main/resources/logback.xml b/jackson-modules/jackson/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/jackson-modules/jackson/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/Address.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/Address.java new file mode 100644 index 0000000000..f0b3b00efe --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/Address.java @@ -0,0 +1,33 @@ +package com.ossez.jackson.dtos; + +public class Address { + + String streetNumber; + String streetName; + String city; + + public String getStreetNumber() { + return streetNumber; + } + + public void setStreetNumber(String streetNumber) { + this.streetNumber = streetNumber; + } + + public String getStreetName() { + return streetName; + } + + public void setStreetName(String streetName) { + this.streetName = streetName; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/MyDto.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/MyDto.java new file mode 100644 index 0000000000..977358a49b --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/MyDto.java @@ -0,0 +1,54 @@ +package com.ossez.jackson.dtos; + +public class MyDto { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDto() { + super(); + } + + public MyDto(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + // + + @Override + public String toString() { + return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]"; + } + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/Person.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/Person.java new file mode 100644 index 0000000000..538128de83 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/Person.java @@ -0,0 +1,47 @@ +package com.ossez.jackson.dtos; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +@JacksonXmlRootElement(localName = "person") +public final class Person { + private String firstName; + private String lastName; + private List phoneNumbers = new ArrayList<>(); + private List
address = new ArrayList<>(); + + public List
getAddress() { + return address; + } + + public void setAddress(List
address) { + this.address = address; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/User.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/User.java new file mode 100644 index 0000000000..59a1a19ef0 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/dtos/User.java @@ -0,0 +1,26 @@ +package com.ossez.jackson.dtos; + +public class User { + public int id; + public String name; + + public User() { + super(); + } + + public User(final int id, final String name) { + this.id = id; + this.name = name; + } + + // API + + public int getId() { + return id; + } + + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/IgnoranceUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/IgnoranceUnitTest.java new file mode 100644 index 0000000000..e0ebbbdb33 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/IgnoranceUnitTest.java @@ -0,0 +1,92 @@ +package com.ossez.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 IgnoranceUnitTest { + 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-modules/jackson/src/test/java/com/ossez/jackson/inheritance/ItemIdRemovedFromUserUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/ItemIdRemovedFromUserUnitTest.java new file mode 100644 index 0000000000..6e9c3f5136 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/ItemIdRemovedFromUserUnitTest.java @@ -0,0 +1,41 @@ +package com.ossez.jackson.inheritance; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ItemIdRemovedFromUserUnitTest { + @Test + public void givenRemoveItemJson_whenDeserialize_shouldHaveProperClassType() throws IOException { + // given + Event event = new ItemIdRemovedFromUser("1", 12345567L, "item_1", 2L); + ObjectMapper objectMapper = new ObjectMapper(); + String eventJson = objectMapper.writeValueAsString(event); + + // when + Event result = new ObjectMapper().readValue(eventJson, Event.class); + + // then + assertTrue(result instanceof ItemIdRemovedFromUser); + assertEquals("item_1", ((ItemIdRemovedFromUser) result).getItemId()); + } + + @Test + public void givenAdddItemJson_whenSerialize_shouldIgnoreIdPropertyFromSuperclass() throws IOException { + // given + Event event = new ItemIdAddedToUser("1", 12345567L, "item_1", 2L); + ObjectMapper objectMapper = new ObjectMapper(); + + // when + String eventJson = objectMapper.writeValueAsString(event); + + // then + assertFalse(eventJson.contains("id")); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/SubTypeHandlingUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/SubTypeHandlingUnitTest.java new file mode 100644 index 0000000000..3b95f7e283 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/SubTypeHandlingUnitTest.java @@ -0,0 +1,43 @@ +package com.ossez.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 SubTypeHandlingUnitTest { + @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-modules/jackson/src/test/java/com/ossez/jackson/inheritance/TypeInfoInclusionUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/TypeInfoInclusionUnitTest.java new file mode 100644 index 0000000000..d47a2e4283 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/inheritance/TypeInfoInclusionUnitTest.java @@ -0,0 +1,61 @@ +package com.ossez.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 TypeInfoInclusionUnitTest { + @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-modules/jackson/src/test/java/com/ossez/jackson/jacksonvsgson/JacksonDeserializeUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/jacksonvsgson/JacksonDeserializeUnitTest.java new file mode 100644 index 0000000000..09ba00bac1 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/jacksonvsgson/JacksonDeserializeUnitTest.java @@ -0,0 +1,38 @@ +package com.ossez.jackson.jacksonvsgson; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import org.junit.Test; +import com.fasterxml.jackson.databind.ObjectMapper; +import static org.junit.Assert.assertEquals; + +public class JacksonDeserializeUnitTest { + + @Test + public void whenSimpleDeserialize_thenCorrect() throws IOException { + + final String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + final ObjectMapper mapper = new ObjectMapper(); + final Movie movie = mapper.readValue(jsonInput, Movie.class); + + final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorJackson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]"; + assertEquals(expectedOutput, movie.toString()); + } + + @Test + public void whenCustomDeserialize_thenCorrect() throws IOException { + + final String jsonInput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + + final ObjectMapper mapper = new ObjectMapper(); + final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + mapper.setDateFormat(df); + + final Movie movie = mapper.readValue(jsonInput, Movie.class); + + final String expectedOutput = "Movie [imdbId=tt0472043, director=Mel Gibson, actors=[ActorJackson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]"; + assertEquals(expectedOutput, movie.toString()); + } + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/jacksonvsgson/JacksonSerializeUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/jacksonvsgson/JacksonSerializeUnitTest.java new file mode 100644 index 0000000000..dccedfd1be --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/jacksonvsgson/JacksonSerializeUnitTest.java @@ -0,0 +1,58 @@ +package com.ossez.jackson.jacksonvsgson; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.TimeZone; + +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class JacksonSerializeUnitTest { + + @Test + public void whenSimpleSerialize_thenCorrect() throws JsonProcessingException, ParseException { + + final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + final ActorJackson rudyYoungblood = new ActorJackson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers")); + final Movie movie = new Movie("tt0472043", "Mel Gibson", Arrays.asList(rudyYoungblood)); + + final ObjectMapper mapper = new ObjectMapper(); + final String jsonResult = mapper.writeValueAsString(movie); + + final String expectedOutput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":401414400000,\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + Assert.assertEquals(jsonResult, expectedOutput); + } + + @Test + public void whenCustomSerialize_thenCorrect() throws ParseException, IOException { + + final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + final ActorJackson rudyYoungblood = new ActorJackson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers")); + final MovieWithNullValue movieWithNullValue = new MovieWithNullValue(null, "Mel Gibson", Arrays.asList(rudyYoungblood)); + + final SimpleModule module = new SimpleModule(); + module.addSerializer(new ActorJacksonSerializer(ActorJackson.class)); + final ObjectMapper mapper = new ObjectMapper(); + + final String jsonResult = mapper.registerModule(module) + .writer(new DefaultPrettyPrinter()) + .writeValueAsString(movieWithNullValue); + + final Object json = mapper.readValue("{\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}],\"imdbID\":null}", Object.class); + final String expectedOutput = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT) + .writeValueAsString(json); + + Assert.assertEquals(jsonResult, expectedOutput); + } +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/jsoncompare/JsonCompareUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/jsoncompare/JsonCompareUnitTest.java new file mode 100644 index 0000000000..7c21b79bc2 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/jsoncompare/JsonCompareUnitTest.java @@ -0,0 +1,126 @@ +package com.ossez.jackson.jsoncompare; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Comparator; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.NumericNode; +import com.fasterxml.jackson.databind.node.TextNode; + +public class JsonCompareUnitTest { + + @Test + public void givenTwoSameJsonDataObjects_whenCompared_thenAreEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\", \"age\": 34 }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"age\": 34, \"fullName\": \"John Miles\" }}"; + + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + assertEquals(actualObj1, actualObj2); + + } + + @Test + public void givenTwoSameNestedJsonDataObjects_whenCompared_thenEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; + + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + assertEquals(actualObj1, actualObj2); + + } + + @Test + public void givenTwoSameListJsonDataObjects_whenCompared_thenEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}"; + + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + assertEquals(actualObj1, actualObj2); + + } + + @Test + public void givenTwoJsonDataObjects_whenComparedUsingCustomNumericNodeComparator_thenEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"name\": \"John\",\"score\":5.0}"; + String s2 = "{\"name\": \"John\",\"score\":5}"; + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + NumericNodeComparator cmp = new NumericNodeComparator(); + + assertNotEquals(actualObj1, actualObj2); + assertTrue(actualObj1.equals(cmp, actualObj2)); + + } + + public class NumericNodeComparator implements Comparator { + @Override + public int compare(JsonNode o1, JsonNode o2) { + if (o1.equals(o2)) { + return 0; + } + if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) { + Double d1 = ((NumericNode) o1).asDouble(); + Double d2 = ((NumericNode) o2).asDouble(); + if (d1.compareTo(d2) == 0) { + return 0; + } + } + return 1; + } + } + + @Test + public void givenTwoJsonDataObjects_whenComparedUsingCustomTextNodeComparator_thenEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"name\": \"JOHN\",\"score\":5}"; + String s2 = "{\"name\": \"John\",\"score\":5}"; + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + TextNodeComparator cmp = new TextNodeComparator(); + + assertNotEquals(actualObj1, actualObj2); + assertTrue(actualObj1.equals(cmp, actualObj2)); + + } + + public class TextNodeComparator implements Comparator { + @Override + public int compare(JsonNode o1, JsonNode o2) { + if (o1.equals(o2)) { + return 0; + } + if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) { + String s1 = ((TextNode) o1).asText(); + String s2 = ((TextNode) o2).asText(); + if (s1.equalsIgnoreCase(s2)) { + return 0; + } + } + return 1; + } + } +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/ExampleStructure.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/ExampleStructure.java new file mode 100644 index 0000000000..79fc5760c1 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/ExampleStructure.java @@ -0,0 +1,18 @@ +package com.ossez.jackson.node; + +import java.io.IOException; +import java.io.InputStream; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class ExampleStructure { + private static ObjectMapper mapper = new ObjectMapper(); + + static JsonNode getExampleRoot() throws IOException { + InputStream exampleInput = ExampleStructure.class.getClassLoader() + .getResourceAsStream("node_example.json"); + JsonNode rootNode = mapper.readTree(exampleInput); + return rootNode; + } +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/JsonNodeIteratorUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/JsonNodeIteratorUnitTest.java new file mode 100644 index 0000000000..b80011e96e --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/JsonNodeIteratorUnitTest.java @@ -0,0 +1,37 @@ +package com.ossez.jackson.node; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +public class JsonNodeIteratorUnitTest { + + private JsonNodeIterator onTest = new JsonNodeIterator(); + private static String expectedYaml = "name: \n" + + " first: Tatu\n" + + " last: Saloranta\n" + + "title: Jackson founder\n" + + "company: FasterXML\n" + + "pets: \n" + + "- type: dog\n" + + " number: 1\n" + + "- type: fish\n" + + " number: 50"; + +@Test +public void givenANodeTree_whenIteratingSubNodes_thenWeFindExpected() throws IOException { + final JsonNode rootNode = ExampleStructure.getExampleRoot(); + + String yaml = onTest.toYaml(rootNode); + System.out.println(yaml.toString()); + + assertEquals(expectedYaml, yaml); + +} + + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/NodeBean.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/NodeBean.java new file mode 100644 index 0000000000..bd38487f1f --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/NodeBean.java @@ -0,0 +1,30 @@ +package com.ossez.jackson.node; + +public class NodeBean { + private int id; + private String name; + + public NodeBean() { + } + + public NodeBean(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; + } +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/NodeOperationUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/NodeOperationUnitTest.java new file mode 100644 index 0000000000..4e801e6ed9 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/node/NodeOperationUnitTest.java @@ -0,0 +1,119 @@ +package com.ossez.jackson.node; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class NodeOperationUnitTest { + private static ObjectMapper mapper = new ObjectMapper(); + + @Test + public void givenAnObject_whenConvertingIntoNode_thenCorrect() { + final NodeBean fromValue = new NodeBean(2016, "baeldung.com"); + + final JsonNode node = mapper.valueToTree(fromValue); + + assertEquals(2016, node.get("id") + .intValue()); + assertEquals("baeldung.com", node.get("name") + .textValue()); + } + + @Test + public void givenANode_whenWritingOutAsAJsonString_thenCorrect() throws IOException { + final String pathToTestFile = "node_to_json_test.json"; + final char[] characterBuffer = new char[50]; + + final JsonNode node = mapper.createObjectNode(); + ((ObjectNode) node).put("id", 2016); + ((ObjectNode) node).put("name", "baeldung.com"); + + try (FileWriter outputStream = new FileWriter(pathToTestFile)) { + mapper.writeValue(outputStream, node); + } + + try (FileReader inputStreamForAssertion = new FileReader(pathToTestFile)) { + inputStreamForAssertion.read(characterBuffer); + } + final String textContentOfTestFile = new String(characterBuffer); + + assertThat(textContentOfTestFile, containsString("2016")); + assertThat(textContentOfTestFile, containsString("baeldung.com")); + + Files.delete(Paths.get(pathToTestFile)); + } + + @Test + public void givenANode_whenConvertingIntoAnObject_thenCorrect() throws JsonProcessingException { + final JsonNode node = mapper.createObjectNode(); + ((ObjectNode) node).put("id", 2016); + ((ObjectNode) node).put("name", "baeldung.com"); + + final NodeBean toValue = mapper.treeToValue(node, NodeBean.class); + + assertEquals(2016, toValue.getId()); + assertEquals("baeldung.com", toValue.getName()); + } + + @Test + public void givenANode_whenAddingIntoATree_thenCorrect() throws IOException { + final JsonNode rootNode = ExampleStructure.getExampleRoot(); + final ObjectNode addedNode = ((ObjectNode) rootNode).putObject("address"); + addedNode.put("city", "Seattle") + .put("state", "Washington") + .put("country", "United States"); + + assertFalse(rootNode.path("address") + .isMissingNode()); + assertEquals("Seattle", rootNode.path("address") + .path("city") + .textValue()); + assertEquals("Washington", rootNode.path("address") + .path("state") + .textValue()); + assertEquals("United States", rootNode.path("address") + .path("country") + .textValue()); + } + + @Test + public void givenANode_whenModifyingIt_thenCorrect() throws IOException { + final String newString = "{\"nick\": \"cowtowncoder\"}"; + final JsonNode newNode = mapper.readTree(newString); + + final JsonNode rootNode = ExampleStructure.getExampleRoot(); + ((ObjectNode) rootNode).set("name", newNode); + + assertFalse(rootNode.path("name") + .path("nick") + .isMissingNode()); + assertEquals("cowtowncoder", rootNode.path("name") + .path("nick") + .textValue()); + } + + @Test + public void givenANode_whenRemovingFromATree_thenCorrect() throws IOException { + final JsonNode rootNode = ExampleStructure.getExampleRoot(); + ((ObjectNode) rootNode).remove("company"); + + assertTrue(rootNode.path("company") + .isMissingNode()); + } + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/optionalwithjackson/OptionalTypeUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/optionalwithjackson/OptionalTypeUnitTest.java new file mode 100644 index 0000000000..89611a74d0 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/optionalwithjackson/OptionalTypeUnitTest.java @@ -0,0 +1,61 @@ +package com.ossez.jackson.optionalwithjackson; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import static io.restassured.path.json.JsonPath.from; +import java.io.IOException; +import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class OptionalTypeUnitTest { + + ObjectMapper mapper = new ObjectMapper().registerModule(new Jdk8Module()); + + @Test + public void givenPresentOptional_whenSerializing_thenValueInJson() throws JsonProcessingException { + + String subTitle = "The Parish Boy's Progress"; + Book book = new Book(); + book.setTitle("Oliver Twist"); + book.setSubTitle(Optional.of(subTitle)); + + String result = mapper.writeValueAsString(book); + + assertThat(from(result).getString("subTitle")).isEqualTo(subTitle); + } + + @Test + public void givenEmptyOptional_whenSerializing_thenNullValue() throws JsonProcessingException { + + Book book = new Book(); + book.setTitle("Oliver Twist"); + book.setSubTitle(Optional.empty()); + + String result = mapper.writeValueAsString(book); + + assertThat(from(result).getString("subTitle")).isNull(); + } + + @Test + public void givenField_whenDeserializingIntoOptional_thenIsPresentWithValue() throws IOException { + + String subTitle = "The Parish Boy's Progress"; + String book = "{ \"title\": \"Oliver Twist\", \"subTitle\": \"" + subTitle + "\" }"; + + Book result = mapper.readValue(book, Book.class); + + assertThat(result.getSubTitle()).isEqualTo(Optional.of(subTitle)); + } + + @Test + public void givenNullField_whenDeserializingIntoOptional_thenIsEmpty() throws IOException { + + String book = "{ \"title\": \"Oliver Twist\", \"subTitle\": null }"; + + Book result = mapper.readValue(book, Book.class); + + assertThat(result.getSubTitle()).isEmpty(); + } +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/JacksonPrettyPrintUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/JacksonPrettyPrintUnitTest.java new file mode 100644 index 0000000000..81278f2fd0 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/JacksonPrettyPrintUnitTest.java @@ -0,0 +1,50 @@ +package com.ossez.jackson.sandbox; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonPrettyPrintUnitTest { + + @Test + public final void whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + // final String fileName = "src/main/resources/example1.json"; + final String fileName = "src/main/resources/example1.json"; + + new File(fileName); + + printJsonFromFile(fileName); + } + + // + + public static void printJsonFromFile(final String fileName) { + System.out.println("-----------------"); + final ObjectMapper mapper = new ObjectMapper(); + try { + final Object json = mapper.readValue(readFile(fileName, StandardCharsets.UTF_8), Object.class); + System.out.println(mapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(json)); + } catch (final IOException e) { + e.printStackTrace(); + } + System.out.println("-----------------"); + } + + static String readFile(final String path, final Charset encoding) throws IOException { + final byte[] encoded = Files.readAllBytes(Paths.get(path)); + return encoding.decode(ByteBuffer.wrap(encoded)) + .toString(); + } + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/SandboxUnitTest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/SandboxUnitTest.java new file mode 100644 index 0000000000..3c67ae9bad --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/SandboxUnitTest.java @@ -0,0 +1,29 @@ +package com.ossez.jackson.sandbox; + +import java.io.IOException; + +import org.junit.Test; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class SandboxUnitTest { + + @Test + public final void whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final TestElement testElement = new TestElement(); + testElement.setX(10); + testElement.setY("adasd"); + final ObjectMapper om = new ObjectMapper(); + om.setVisibility(om.getSerializationConfig() + .getDefaultVisibilityChecker() + .withFieldVisibility(JsonAutoDetect.Visibility.ANY) + .withGetterVisibility(JsonAutoDetect.Visibility.NONE)); + + final String serialized = om.writeValueAsString(testElement); + System.err.println(serialized); + } + +} diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/TestElement.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/TestElement.java new file mode 100644 index 0000000000..8d44842054 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/sandbox/TestElement.java @@ -0,0 +1,25 @@ +package com.ossez.jackson.sandbox; + +public class TestElement { + + int x; + + private transient String y; + + public int getX() { + return x; + } + + public void setX(final int x) { + this.x = x; + } + + public String getY() { + return y; + } + + public void setY(final String y) { + this.y = y; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/test/UnitTestSuite.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/test/UnitTestSuite.java new file mode 100644 index 0000000000..5f715ec599 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/test/UnitTestSuite.java @@ -0,0 +1,14 @@ +package com.ossez.jackson.test; + +import com.ossez.jackson.sandbox.JacksonPrettyPrintUnitTest; +import com.ossez.jackson.sandbox.SandboxUnitTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ // @formatter:off + JacksonPrettyPrintUnitTest.class + , SandboxUnitTest.class +}) // @formatter:on +public class UnitTestSuite { +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/IEntity.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/IEntity.java new file mode 100644 index 0000000000..cc2269ad96 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/IEntity.java @@ -0,0 +1,5 @@ +package com.ossez.jackson.try1; + +public interface IEntity { + public int getId(); +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/RestLoaderRequest.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/RestLoaderRequest.java new file mode 100644 index 0000000000..fdeac9b7a3 --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/RestLoaderRequest.java @@ -0,0 +1,38 @@ +package com.ossez.jackson.try1; + +import java.io.Serializable; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = RestLoaderRequestDeserializer.class) +// @Produces(MediaType.APPLICATION_JSON) +public class RestLoaderRequest implements Serializable { + private T entity; // entity to load field to + private String className; // actual class of entity + private String fieldName; // fieldName to lazy REST load + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(final String fieldName) { + this.fieldName = fieldName; + } + + public String getClassName() { + return className; + } + + public void setClassName(final String className) { + this.className = className; + } + + public T getEntity() { + return entity; + } + + public void setEntity(final T entity) { + this.entity = entity; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/RestLoaderRequestDeserializer.java b/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/RestLoaderRequestDeserializer.java new file mode 100644 index 0000000000..b49d6b1d8e --- /dev/null +++ b/jackson-modules/jackson/src/test/java/com/ossez/jackson/try1/RestLoaderRequestDeserializer.java @@ -0,0 +1,48 @@ +package com.ossez.jackson.try1; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class RestLoaderRequestDeserializer extends StdDeserializer> { + private static final long serialVersionUID = -4245207329377196889L; + + public RestLoaderRequestDeserializer() { + this(null); + } + + public RestLoaderRequestDeserializer(final Class vc) { + super(vc); + } + + @Override + public RestLoaderRequest deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { + try { + final ObjectCodec objectCodec = jp.getCodec(); + final JsonNode node = objectCodec.readTree(jp); + final String className = node.get("className") + .textValue(); + final String fieldName = node.get("fieldName") + .textValue(); + + final Class clazz = Class.forName(className); + + final JsonNode rawEntityNode = node.get("entity"); + // How to deserialize rawEntityNode to T based on className ? + + final RestLoaderRequest request = new RestLoaderRequest(); + request.setClassName(className); + request.setFieldName(fieldName); + } catch (final ClassNotFoundException e) { + e.printStackTrace(); + } + + return null; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/resources/author-jsonpropertyorder-schema.json b/jackson-modules/jackson/src/test/resources/author-jsonpropertyorder-schema.json new file mode 100644 index 0000000000..8e7a85372c --- /dev/null +++ b/jackson-modules/jackson/src/test/resources/author-jsonpropertyorder-schema.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Author", + "description": "An author", + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object" + } + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "items", + "firstName", + "lastName", + "id" + ] +} \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/resources/node_example-1.json b/jackson-modules/jackson/src/test/resources/node_example-1.json new file mode 100644 index 0000000000..e766981a50 --- /dev/null +++ b/jackson-modules/jackson/src/test/resources/node_example-1.json @@ -0,0 +1,65 @@ +{ + "rootEquipmentId": "830AFC79-E36E-41A4-8944-BDB71EEEC7AF", + "equipmentId": "7C82F833-A495-42E7-8CBE-2CEC42992DD1", + "startTime": "2021-09-01T00:00:00.000Z", + "endTime": "2021-09-01T03:00:00.000Z", + "testMaxBins": 36, + "testData": [ + { + "version": "v1", + "timestamp": "2021-09-01T00:40:00.000Z", + "event": { + "AlertType": "kpi", + "AlertId": "6B341AB0-971D-494E-9522-A23500BF7C9D", + "SourceAspectId": "80CB7FE9-9762-48C0-8027-CBE3EC517D0D", + "State": "INSUFFICIENT", + "SourceId": "7C82F833-A495-42E7-8CBE-2CEC42992DD1", + "Period": 1800, + "Severity": "1", + "SourceAspectName": "TagName" + } + }, + { + "version": "v1", + "timestamp": "2021-09-01T01:10:00.000Z", + "event": { + "AlertType": "kpi", + "AlertId": "6B341AB0-971D-494E-9522-A23500BF7C9D", + "SourceAspectId": "80CB7FE9-9762-48C0-8027-CBE3EC517D0D", + "State": "INSUFFICIENT", + "SourceId": "7C82F833-A495-42E7-8CBE-2CEC42992DD1", + "Period": 1800, + "Severity": "1", + "SourceAspectName": "TagName" + } + }, + { + "version": "v1", + "timestamp": "2021-09-01T02:10:00.000Z", + "event": { + "AlertType": "kpi", + "AlertId": "6B341AB0-971D-494E-9522-A23500BF7C9D", + "SourceAspectId": "80CB7FE9-9762-48C0-8027-CBE3EC517D0D", + "State": "OK", + "SourceId": "7C82F833-A495-42E7-8CBE-2CEC42992DD1", + "Period": 1800, + "Severity": "1", + "SourceAspectName": "TagName" + } + }, + { + "version": "v1", + "timestamp": "2021-09-01T02:40:00.000Z", + "event": { + "AlertType": "kpi", + "AlertId": "6B341AB0-971D-494E-9522-A23500BF7C9D", + "SourceAspectId": "80CB7FE9-9762-48C0-8027-CBE3EC517D0D", + "State": "OK", + "SourceId": "7C82F833-A495-42E7-8CBE-2CEC42992DD1", + "Period": 1800, + "Severity": "1", + "SourceAspectName": "TagName" + } + } + ] +} diff --git a/jackson-modules/jackson/src/test/resources/node_example.json b/jackson-modules/jackson/src/test/resources/node_example.json new file mode 100644 index 0000000000..d57c1df6e3 --- /dev/null +++ b/jackson-modules/jackson/src/test/resources/node_example.json @@ -0,0 +1,18 @@ +{ + "name": { + "first": "Tatu", + "last": "Saloranta" + }, + "title": "Jackson founder", + "company": "FasterXML", + "pets": [ + { + "type": "dog", + "number": 1 + }, + { + "type": "fish", + "number": 50 + } + ] +} \ No newline at end of file