From dc220b25ffad878c7493a336804071aab7e0f833 Mon Sep 17 00:00:00 2001 From: YuCheng Hu Date: Tue, 30 Apr 2024 12:07:39 -0400 Subject: [PATCH] bring jackson back --- .../jackson-custom-conversions/README.md | 9 + .../jackson-custom-conversions/pom.xml | 44 ++++ ...derSerializerWithCallingOwnSerializer.java | 29 +++ ...SerializerWithDefaultSerializerStored.java | 34 +++ ...derSerializerWithInternalObjectMapper.java | 33 +++ ...olderSerializerWithSerializerProvider.java | 28 +++ .../deserialization/ActorJackson.java | 61 ++++++ .../com/baeldung/deserialization/Item.java | 32 +++ .../deserialization/ItemDeserializer.java | 39 ++++ .../ItemDeserializerOnClass.java | 39 ++++ .../deserialization/ItemWithDeserializer.java | 31 +++ .../com/baeldung/deserialization/Movie.java | 50 +++++ .../com/baeldung/deserialization/User.java | 26 +++ .../java/com/baeldung/serialization/Item.java | 32 +++ .../serialization/ItemSerializer.java | 31 +++ .../serialization/ItemSerializerOnClass.java | 31 +++ .../serialization/ItemWithSerializer.java | 32 +++ .../java/com/baeldung/serialization/User.java | 26 +++ .../java/com/baeldung/skipfields/Address.java | 40 ++++ .../java/com/baeldung/skipfields/Hidable.java | 8 + .../skipfields/HidableSerializer.java | 29 +++ .../baeldung/skipfields/MyDtoWithFilter.java | 50 +++++ .../java/com/baeldung/skipfields/Person.java | 40 ++++ .../CallingDefaultSerializerUnitTest.java | 164 +++++++++++++++ .../CustomDeserializationUnitTest.java | 81 ++++++++ .../CustomSerializationUnitTest.java | 49 +++++ .../IgnoreFieldsWithFilterUnitTest.java | 87 ++++++++ .../JacksonDynamicIgnoreUnitTest.java | 88 ++++++++ jackson-modules/jackson-exceptions/README.md | 7 + jackson-modules/jackson-exceptions/pom.xml | 26 +++ .../java/com/baeldung/exceptions/User.java | 26 +++ .../baeldung/exceptions/UserWithConflict.java | 25 +++ .../UserWithNoDefaultConstructor.java | 21 ++ .../exceptions/UserWithPrivateFields.java | 16 ++ .../com/baeldung/exceptions/UserWithRoot.java | 18 ++ .../java/com/baeldung/exceptions/Zoo.java | 22 ++ .../baeldung/exceptions/ZooConfigured.java | 25 +++ .../mappingexception/MyDtoNoAccessors.java | 21 ++ .../MyDtoNoAccessorsAndFieldVisibility.java | 25 +++ .../exceptions/JacksonExceptionsUnitTest.java | 195 ++++++++++++++++++ .../JacksonMappingExceptionUnitTest.java | 51 +++++ jackson-modules/pom.xml | 56 +++++ 42 files changed, 1777 insertions(+) create mode 100644 jackson-modules/jackson-custom-conversions/README.md create mode 100644 jackson-modules/jackson-custom-conversions/pom.xml create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithCallingOwnSerializer.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithDefaultSerializerStored.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithInternalObjectMapper.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithSerializerProvider.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ActorJackson.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Item.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializer.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializerOnClass.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemWithDeserializer.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Movie.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/User.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/Item.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializer.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializerOnClass.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemWithSerializer.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/User.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Address.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Hidable.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/HidableSerializer.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/MyDtoWithFilter.java create mode 100644 jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Person.java create mode 100644 jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/defaultserializercustomserializer/CallingDefaultSerializerUnitTest.java create mode 100644 jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/deserialization/CustomDeserializationUnitTest.java create mode 100644 jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/serialization/CustomSerializationUnitTest.java create mode 100644 jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/IgnoreFieldsWithFilterUnitTest.java create mode 100644 jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/JacksonDynamicIgnoreUnitTest.java create mode 100644 jackson-modules/jackson-exceptions/README.md create mode 100644 jackson-modules/jackson-exceptions/pom.xml create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/User.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithConflict.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithNoDefaultConstructor.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithPrivateFields.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithRoot.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/Zoo.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/ZooConfigured.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessors.java create mode 100644 jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessorsAndFieldVisibility.java create mode 100644 jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java create mode 100644 jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java create mode 100644 jackson-modules/pom.xml diff --git a/jackson-modules/jackson-custom-conversions/README.md b/jackson-modules/jackson-custom-conversions/README.md new file mode 100644 index 0000000000..68e9a6d50d --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/README.md @@ -0,0 +1,9 @@ +## Jackson Custom Conversions + +This module contains articles about Jackson custom conversions. + +### Relevant Articles: +- [Jackson – Custom Serializer](https://www.baeldung.com/jackson-custom-serialization) +- [Getting Started with Custom Deserialization in Jackson](https://www.baeldung.com/jackson-deserialization) +- [Serialize Only Fields that meet a Custom Criteria with Jackson](https://www.baeldung.com/jackson-serialize-field-custom-criteria) +- [Calling Default Serializer from Custom Serializer in Jackson](https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer) diff --git a/jackson-modules/jackson-custom-conversions/pom.xml b/jackson-modules/jackson-custom-conversions/pom.xml new file mode 100644 index 0000000000..8772558bf3 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + jackson-custom-conversions + 0.0.1-SNAPSHOT + jackson-custom-conversions + + + 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.core + jackson-core + ${jackson.version} + + + + + jackson-custom-conversions + + + src/main/resources + true + + + + + \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithCallingOwnSerializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithCallingOwnSerializer.java new file mode 100644 index 0000000000..544a4c6d1a --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithCallingOwnSerializer.java @@ -0,0 +1,29 @@ +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 FolderSerializerWithCallingOwnSerializer extends StdSerializer { + + public FolderSerializerWithCallingOwnSerializer() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + provider.defaultSerializeField("files", value.getFiles(), gen); + + provider.defaultSerializeField("details", value, gen); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithDefaultSerializerStored.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithDefaultSerializerStored.java new file mode 100644 index 0000000000..558b303301 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithDefaultSerializerStored.java @@ -0,0 +1,34 @@ +package com.baeldung.defaultserializercustomserializer; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializerWithDefaultSerializerStored extends StdSerializer { + + private final JsonSerializer defaultSerializer; + + public FolderSerializerWithDefaultSerializerStored(JsonSerializer defaultSerializer) { + super(Folder.class); + this.defaultSerializer = defaultSerializer; + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + provider.defaultSerializeField("files", value.getFiles(), gen); + + gen.writeFieldName("details"); + defaultSerializer.serialize(value, gen, provider); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithInternalObjectMapper.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithInternalObjectMapper.java new file mode 100644 index 0000000000..1ad51c63c0 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithInternalObjectMapper.java @@ -0,0 +1,33 @@ +package com.baeldung.defaultserializercustomserializer; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializerWithInternalObjectMapper extends StdSerializer { + + public FolderSerializerWithInternalObjectMapper() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + // we access internal mapper to delegate the serialization of File list + ObjectMapper mapper = (ObjectMapper) gen.getCodec(); + + gen.writeFieldName("files"); + String stringValue = mapper.writeValueAsString(value.getFiles()); + gen.writeRawValue(stringValue); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithSerializerProvider.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithSerializerProvider.java new file mode 100644 index 0000000000..8aeb28b3d0 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/defaultserializercustomserializer/FolderSerializerWithSerializerProvider.java @@ -0,0 +1,28 @@ +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 FolderSerializerWithSerializerProvider extends StdSerializer { + + public FolderSerializerWithSerializerProvider() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + // we delegate the File list serialization to its default serializer + provider.defaultSerializeField("files", value.getFiles(), gen); + + gen.writeEndObject(); + + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ActorJackson.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ActorJackson.java new file mode 100644 index 0000000000..4bf3bc57f6 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ActorJackson.java @@ -0,0 +1,61 @@ +package com.baeldung.deserialization; + +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-custom-conversions/src/main/java/com/baeldung/deserialization/Item.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Item.java new file mode 100644 index 0000000000..e6234bb6e9 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Item.java @@ -0,0 +1,32 @@ +package com.baeldung.deserialization; + +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; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializer.java new file mode 100644 index 0000000000..7ae2faa04d --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializer.java @@ -0,0 +1,39 @@ +package com.baeldung.deserialization; + +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; +import com.fasterxml.jackson.databind.node.IntNode; + +public class ItemDeserializer extends StdDeserializer { + + private static final long serialVersionUID = 1883547683050039861L; + + public ItemDeserializer() { + this(null); + } + + public ItemDeserializer(final Class vc) { + super(vc); + } + + /** + * {"id":1,"itemNr":"theItem","owner":2} + */ + @Override + public Item deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { + final JsonNode node = jp.getCodec() + .readTree(jp); + final int id = (Integer) ((IntNode) node.get("id")).numberValue(); + final String itemName = node.get("itemName") + .asText(); + final int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue(); + + return new Item(id, itemName, new User(userId, null)); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializerOnClass.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializerOnClass.java new file mode 100644 index 0000000000..b9db114c4a --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemDeserializerOnClass.java @@ -0,0 +1,39 @@ +package com.baeldung.deserialization; + +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; +import com.fasterxml.jackson.databind.node.IntNode; + +public class ItemDeserializerOnClass extends StdDeserializer { + + private static final long serialVersionUID = 5579141241817332594L; + + public ItemDeserializerOnClass() { + this(null); + } + + public ItemDeserializerOnClass(final Class vc) { + super(vc); + } + + /** + * {"id":1,"itemNr":"theItem","owner":2} + */ + @Override + public ItemWithDeserializer deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { + final JsonNode node = jp.getCodec() + .readTree(jp); + final int id = (Integer) ((IntNode) node.get("id")).numberValue(); + final String itemName = node.get("itemName") + .asText(); + final int userId = (Integer) ((IntNode) node.get("owner")).numberValue(); + + return new ItemWithDeserializer(id, itemName, new User(userId, null)); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemWithDeserializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemWithDeserializer.java new file mode 100644 index 0000000000..1ab36e4acd --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/ItemWithDeserializer.java @@ -0,0 +1,31 @@ +package com.baeldung.deserialization; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = ItemDeserializerOnClass.class) +public class ItemWithDeserializer { + public final int id; + public final String itemName; + public final User owner; + + public ItemWithDeserializer(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Movie.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Movie.java new file mode 100644 index 0000000000..fdb107dca2 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/Movie.java @@ -0,0 +1,50 @@ +package com.baeldung.deserialization; + +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-custom-conversions/src/main/java/com/baeldung/deserialization/User.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/User.java new file mode 100644 index 0000000000..d22a85aafd --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/deserialization/User.java @@ -0,0 +1,26 @@ +package com.baeldung.deserialization; + +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-custom-conversions/src/main/java/com/baeldung/serialization/Item.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/Item.java new file mode 100644 index 0000000000..52a73b048c --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/Item.java @@ -0,0 +1,32 @@ +package com.baeldung.serialization; + +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; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializer.java new file mode 100644 index 0000000000..dc0b5e1c88 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializer.java @@ -0,0 +1,31 @@ +package com.baeldung.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 ItemSerializer extends StdSerializer { + + private static final long serialVersionUID = 6739170890621978901L; + + public ItemSerializer() { + this(null); + } + + public ItemSerializer(final Class t) { + super(t); + } + + @Override + public final void serialize(final Item value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeNumberField("id", value.id); + jgen.writeStringField("itemName", value.itemName); + jgen.writeNumberField("owner", value.owner.id); + jgen.writeEndObject(); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializerOnClass.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializerOnClass.java new file mode 100644 index 0000000000..8f56c349f2 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemSerializerOnClass.java @@ -0,0 +1,31 @@ +package com.baeldung.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 ItemSerializerOnClass extends StdSerializer { + + private static final long serialVersionUID = -1760959597313610409L; + + public ItemSerializerOnClass() { + this(null); + } + + public ItemSerializerOnClass(final Class t) { + super(t); + } + + @Override + public final void serialize(final ItemWithSerializer value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeNumberField("id", value.id); + jgen.writeStringField("itemName", value.itemName); + jgen.writeNumberField("owner", value.owner.id); + jgen.writeEndObject(); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemWithSerializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemWithSerializer.java new file mode 100644 index 0000000000..5b38ad1af6 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/ItemWithSerializer.java @@ -0,0 +1,32 @@ +package com.baeldung.serialization; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize(using = ItemSerializerOnClass.class) +public class ItemWithSerializer { + public final int id; + public final String itemName; + public final User owner; + + public ItemWithSerializer(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/User.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/User.java new file mode 100644 index 0000000000..b01ccc9ffb --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/serialization/User.java @@ -0,0 +1,26 @@ +package com.baeldung.serialization; + +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-custom-conversions/src/main/java/com/baeldung/skipfields/Address.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Address.java new file mode 100644 index 0000000000..a394bbc180 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Address.java @@ -0,0 +1,40 @@ +package com.baeldung.skipfields; + +public class Address implements Hidable { + private String city; + private String country; + private boolean hidden; + + public Address(final String city, final String country, final boolean hidden) { + super(); + this.city = city; + this.country = country; + this.hidden = hidden; + } + + public String getCity() { + return city; + } + + public void setCity(final String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(final String country) { + this.country = country; + } + + @Override + public boolean isHidden() { + return hidden; + } + + public void setHidden(final boolean hidden) { + this.hidden = hidden; + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Hidable.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Hidable.java new file mode 100644 index 0000000000..fff7f81d1e --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Hidable.java @@ -0,0 +1,8 @@ +package com.baeldung.skipfields; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties("hidden") +public interface Hidable { + boolean isHidden(); +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/HidableSerializer.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/HidableSerializer.java new file mode 100644 index 0000000000..8b300444c0 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/HidableSerializer.java @@ -0,0 +1,29 @@ +package com.baeldung.skipfields; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class HidableSerializer extends JsonSerializer { + + private JsonSerializer defaultSerializer; + + public HidableSerializer(final JsonSerializer serializer) { + defaultSerializer = serializer; + } + + @Override + public void serialize(final Hidable value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { + if (value.isHidden()) + return; + defaultSerializer.serialize(value, jgen, provider); + } + + @Override + public boolean isEmpty(final SerializerProvider provider, final Hidable value) { + return (value == null || value.isHidden()); + } +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/MyDtoWithFilter.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/MyDtoWithFilter.java new file mode 100644 index 0000000000..50492c337a --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/MyDtoWithFilter.java @@ -0,0 +1,50 @@ +package com.baeldung.skipfields; + +import com.fasterxml.jackson.annotation.JsonFilter; + +@JsonFilter("myFilter") +public class MyDtoWithFilter { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDtoWithFilter() { + super(); + } + + public MyDtoWithFilter(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; + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Person.java b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Person.java new file mode 100644 index 0000000000..e1501947d3 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/main/java/com/baeldung/skipfields/Person.java @@ -0,0 +1,40 @@ +package com.baeldung.skipfields; + +public class Person implements Hidable { + private String name; + private Address address; + private boolean hidden; + + public Person(final String name, final Address address, final boolean hidden) { + super(); + this.name = name; + this.address = address; + this.hidden = hidden; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(final Address address) { + this.address = address; + } + + @Override + public boolean isHidden() { + return hidden; + } + + public void setHidden(final boolean hidden) { + this.hidden = hidden; + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/defaultserializercustomserializer/CallingDefaultSerializerUnitTest.java b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/defaultserializercustomserializer/CallingDefaultSerializerUnitTest.java new file mode 100644 index 0000000000..c8b4ec7e1a --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/defaultserializercustomserializer/CallingDefaultSerializerUnitTest.java @@ -0,0 +1,164 @@ +package com.baeldung.defaultserializercustomserializer; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class CallingDefaultSerializerUnitTest { + + private ObjectMapper mapper; + private Folder mockFolder; + private TypeReference> mapType; + + @Before + public void setup() { + + mapType = new TypeReference>() { + }; + + mapper = new ObjectMapper(); + + mockFolder = new Folder(); + mockFolder.setId(1L); + mockFolder.setName("Root Folder"); + mockFolder.setOwner("root"); + mockFolder.setCreated(Date.from(Instant.now().minusSeconds(60))); + mockFolder.setModified(Date.from(Instant.now().minusSeconds(30))); + mockFolder.setLastAccess(Date.from(Instant.now())); + + File file1 = new File(); + file1.setId(1L); + file1.setName("File 1"); + + File file2 = new File(); + file2.setId(2L); + file2.setName("File 2"); + + List files = new ArrayList<>(); + files.add(file1); + files.add(file2); + mockFolder.setFiles(files); + + } + + @Test + public void givenFolder_whenSerialized_onlyNameAndFilesFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializer()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + } + + @Test + public void givenFolder_whenSerializedWithSerializerProvider_onlyNameAndFilesFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializerWithSerializerProvider()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + } + + @Test + public void givenFolder_whenSerializedWithInternalObjectMapper_onlyNameAndFilesFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializerWithInternalObjectMapper()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + } + + @Test(expected = StackOverflowError.class) + public void givenFolder_whenSerializedWithCallingOwnSerializer_exceptionOccured() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializerWithCallingOwnSerializer()); + mapper.registerModule(module); + + mapper.writeValueAsString(mockFolder); + + } + + @Test + public void givenFolder_whenSerializedWithDefaultSerializerStored_NameAndFilesAndDetailsFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.setSerializerModifier(new FolderBeanSerializerModifier()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + Map actualDetails = (Map) actual.get("details"); + assertTrue(actualDetails.containsKey("id")); + assertTrue(actualDetails.containsKey("name")); + assertTrue(actualDetails.containsKey("owner")); + assertTrue(actualDetails.containsKey("created")); + assertTrue(actualDetails.containsKey("modified")); + assertTrue(actualDetails.containsKey("lastAccess")); + + assertEquals(mockFolder.getId().longValue(), ((Number)actualDetails.get("id")).longValue()); + assertEquals(mockFolder.getName(), actualDetails.get("name")); + assertEquals(mockFolder.getOwner(), actualDetails.get("owner")); + assertEquals(mockFolder.getCreated(), new Date((long) actualDetails.get("created"))); + assertEquals(mockFolder.getModified(), new Date((long) actualDetails.get("modified"))); + assertEquals(mockFolder.getLastAccess(), new Date((long) actualDetails.get("lastAccess"))); + + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/deserialization/CustomDeserializationUnitTest.java b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/deserialization/CustomDeserializationUnitTest.java new file mode 100644 index 0000000000..17016149a2 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/deserialization/CustomDeserializationUnitTest.java @@ -0,0 +1,81 @@ +package com.baeldung.deserialization; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; +import org.junit.Test; + +import java.io.IOException; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +public class CustomDeserializationUnitTest { + + @Test + public final void whenDeserializingTheStandardRepresentation_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final String json = "{\"id\":1,\"itemName\":\"theItem\",\"owner\":{\"id\":2,\"name\":\"theUser\"}}"; + + final Item readValue = new ObjectMapper().readValue(json, Item.class); + assertThat(readValue, notNullValue()); + } + + @Test + public final void whenDeserializingANonStandardRepresentation_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final String json = "{\"id\":1,\"itemName\":\"theItem\",\"createdBy\":2}"; + final ObjectMapper mapper = new ObjectMapper(); + + final SimpleModule module = new SimpleModule(); + module.addDeserializer(Item.class, new ItemDeserializer()); + mapper.registerModule(module); + + final Item readValue = mapper.readValue(json, Item.class); + assertThat(readValue, notNullValue()); + } + + @Test + public final void givenDeserializerIsOnClass_whenDeserializingCustomRepresentation_thenCorrect() throws JsonParseException, JsonMappingException, IOException { + final String json = "{\"id\":1,\"itemName\":\"theItem\",\"owner\":2}"; + + final ItemWithDeserializer readValue = new ObjectMapper().readValue(json, ItemWithDeserializer.class); + assertThat(readValue, notNullValue()); + } + + @Test + public void whenDeserialisingZonedDateTimeWithDefaults_thenTimeZoneIsNotPreserved() throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + // construct a new instance of ZonedDateTime + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Berlin")); + String converted = objectMapper.writeValueAsString(now); + // restore an instance of ZonedDateTime from String + ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class); + assertThat(now, is(not(restored))); + } + + @Test + public void whenDeserialisingZonedDateTimeWithFeaturesDisabled_thenTimeZoneIsPreserved() throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID); + objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); + // construct a new instance of ZonedDateTime + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Berlin")); + String converted = objectMapper.writeValueAsString(now); + // restore an instance of ZonedDateTime from String + ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class); + assertThat(restored, is(now)); + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/serialization/CustomSerializationUnitTest.java b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/serialization/CustomSerializationUnitTest.java new file mode 100644 index 0000000000..9c46a86fd8 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/serialization/CustomSerializationUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.serialization; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.List; +import org.junit.Test; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +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.module.SimpleModule; +import com.google.common.collect.Lists; + +public class CustomSerializationUnitTest { + + @Test + public final void whenSerializing_thenNoExceptions() throws JsonGenerationException, JsonMappingException, IOException { + final Item myItem = new Item(1, "theItem", new User(2, "theUser")); + final String serialized = new ObjectMapper().writeValueAsString(myItem); + } + + @Test + public final void whenSerializingWithCustomSerializer_thenNoExceptions() throws JsonGenerationException, JsonMappingException, IOException { + final Item myItem = new Item(1, "theItem", new User(2, "theUser")); + + final ObjectMapper mapper = new ObjectMapper(); + + final SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(Item.class, new ItemSerializer()); + mapper.registerModule(simpleModule); + + final String serialized = mapper.writeValueAsString(myItem); + } + + @Test + public final void givenSerializerRegisteredOnClass_whenSerializingWithCustomSerializer_thenNoExceptions() throws JsonGenerationException, JsonMappingException, IOException { + final ItemWithSerializer myItem = new ItemWithSerializer(1, "theItem", new User(2, "theUser")); + + final String serialized = new ObjectMapper().writeValueAsString(myItem); + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/IgnoreFieldsWithFilterUnitTest.java b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/IgnoreFieldsWithFilterUnitTest.java new file mode 100644 index 0000000000..ec753019b2 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/IgnoreFieldsWithFilterUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.skipfields; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.FilterProvider; +import com.fasterxml.jackson.databind.ser.PropertyFilter; +import com.fasterxml.jackson.databind.ser.PropertyWriter; +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; +import org.junit.Test; + +import java.io.IOException; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; + +public class IgnoreFieldsWithFilterUnitTest { + + @Test + public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { + final ObjectMapper mapper = new ObjectMapper(); + final SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAllExcept("intValue"); + final FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter); + + final MyDtoWithFilter dtoObject = new MyDtoWithFilter(); + dtoObject.setIntValue(12); + + final String dtoAsString = mapper.writer(filters) + .writeValueAsString(dtoObject); + + assertThat(dtoAsString, not(containsString("intValue"))); + assertThat(dtoAsString, containsString("booleanValue")); + assertThat(dtoAsString, containsString("stringValue")); + } + + @Test + public final void givenTypeHasFilterThatIgnoresNegativeInt_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { + final PropertyFilter theFilter = new SimpleBeanPropertyFilter() { + @Override + public final void serializeAsField(final Object pojo, final JsonGenerator jgen, final SerializerProvider provider, final PropertyWriter writer) throws Exception { + if (include(writer)) { + if (!writer.getName() + .equals("intValue")) { + writer.serializeAsField(pojo, jgen, provider); + return; + } + + final int intValue = ((MyDtoWithFilter) pojo).getIntValue(); + if (intValue >= 0) { + writer.serializeAsField(pojo, jgen, provider); + } + } else if (!jgen.canOmitFields()) { // since 2.3 + writer.serializeAsOmittedField(pojo, jgen, provider); + } + } + + @Override + protected final boolean include(final BeanPropertyWriter writer) { + return true; + } + + @Override + protected final boolean include(final PropertyWriter writer) { + return true; + } + }; + final FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter); + + final MyDtoWithFilter dtoObject = new MyDtoWithFilter(); + dtoObject.setIntValue(-1); + + final ObjectMapper mapper = new ObjectMapper(); + final String dtoAsString = mapper.writer(filters) + .writeValueAsString(dtoObject); + + assertThat(dtoAsString, not(containsString("intValue"))); + assertThat(dtoAsString, containsString("booleanValue")); + assertThat(dtoAsString, containsString("stringValue")); + } + +} diff --git a/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/JacksonDynamicIgnoreUnitTest.java b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/JacksonDynamicIgnoreUnitTest.java new file mode 100644 index 0000000000..2fd59e2a82 --- /dev/null +++ b/jackson-modules/jackson-custom-conversions/src/test/java/com/baeldung/skipfields/JacksonDynamicIgnoreUnitTest.java @@ -0,0 +1,88 @@ +package com.baeldung.skipfields; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; + +public class JacksonDynamicIgnoreUnitTest { + + private ObjectMapper mapper = new ObjectMapper(); + + @Before + public void setUp() { + mapper.setSerializationInclusion(Include.NON_EMPTY); + mapper.registerModule(new SimpleModule() { + @Override + public void setupModule(final SetupContext context) { + super.setupModule(context); + context.addBeanSerializerModifier(new BeanSerializerModifier() { + @Override + public JsonSerializer modifySerializer(final SerializationConfig config, final BeanDescription beanDesc, final JsonSerializer serializer) { + if (Hidable.class.isAssignableFrom(beanDesc.getBeanClass())) { + return new HidableSerializer((JsonSerializer) serializer); + } + return serializer; + } + }); + } + }); + } + + @Test + public void whenNotHidden_thenCorrect() throws JsonProcessingException { + final Address ad = new Address("ny", "usa", false); + final Person person = new Person("john", ad, false); + final String result = mapper.writeValueAsString(person); + + assertTrue(result.contains("name")); + assertTrue(result.contains("john")); + assertTrue(result.contains("address")); + assertTrue(result.contains("usa")); + } + + @Test + public void whenAddressHidden_thenCorrect() throws JsonProcessingException { + final Address ad = new Address("ny", "usa", true); + final Person person = new Person("john", ad, false); + final String result = mapper.writeValueAsString(person); + + assertTrue(result.contains("name")); + assertTrue(result.contains("john")); + assertFalse(result.contains("address")); + assertFalse(result.contains("usa")); + } + + @Test + public void whenAllHidden_thenCorrect() throws JsonProcessingException { + final Address ad = new Address("ny", "usa", false); + final Person person = new Person("john", ad, true); + final String result = mapper.writeValueAsString(person); + + assertTrue(result.length() == 0); + } + + @Test + public void whenSerializeList_thenCorrect() throws JsonProcessingException { + final Address ad1 = new Address("tokyo", "jp", true); + final Address ad2 = new Address("london", "uk", false); + final Address ad3 = new Address("ny", "usa", false); + final Person p1 = new Person("john", ad1, false); + final Person p2 = new Person("tom", ad2, true); + final Person p3 = new Person("adam", ad3, false); + + final String result = mapper.writeValueAsString(Arrays.asList(p1, p2, p3)); + } +} diff --git a/jackson-modules/jackson-exceptions/README.md b/jackson-modules/jackson-exceptions/README.md new file mode 100644 index 0000000000..6f082aaaa5 --- /dev/null +++ b/jackson-modules/jackson-exceptions/README.md @@ -0,0 +1,7 @@ +## Jackson Exceptions + +This module contains articles about Jackson exceptions. + +### Relevant Articles: +- [Jackson Exceptions – Problems and Solutions](https://www.baeldung.com/jackson-exception) +- [Jackson – JsonMappingException (No serializer found for class)](https://www.baeldung.com/jackson-jsonmappingexception) diff --git a/jackson-modules/jackson-exceptions/pom.xml b/jackson-modules/jackson-exceptions/pom.xml new file mode 100644 index 0000000000..bb2a9b1810 --- /dev/null +++ b/jackson-modules/jackson-exceptions/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + jackson-exceptions + 0.0.1-SNAPSHOT + jackson-exceptions + + + com.ossez + jackson-modules + 0.0.2-SNAPSHOT + + + + jackson-exceptions + + + src/main/resources + true + + + + + \ No newline at end of file diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/User.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/User.java new file mode 100644 index 0000000000..e0e77c658e --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/User.java @@ -0,0 +1,26 @@ +package com.baeldung.exceptions; + +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-exceptions/src/main/java/com/baeldung/exceptions/UserWithConflict.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithConflict.java new file mode 100644 index 0000000000..5adbb7b01e --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithConflict.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +public class UserWithConflict { + public int id; + public String name; + boolean checked; + + public UserWithConflict() { + super(); + } + + public UserWithConflict(final int id, final String name, final boolean checked) { + this.id = id; + this.name = name; + this.checked = checked; + } + + public boolean getChecked() { + return checked; + } + + public boolean isChecked() { + return checked; + } +} diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithNoDefaultConstructor.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithNoDefaultConstructor.java new file mode 100644 index 0000000000..c75b06ed6a --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithNoDefaultConstructor.java @@ -0,0 +1,21 @@ +package com.baeldung.exceptions; + +public class UserWithNoDefaultConstructor { + + private int id; + private String name; + + public UserWithNoDefaultConstructor(final int id, final String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithPrivateFields.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithPrivateFields.java new file mode 100644 index 0000000000..c10020bd85 --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithPrivateFields.java @@ -0,0 +1,16 @@ +package com.baeldung.exceptions; + +public class UserWithPrivateFields { + int id; + String name; + + public UserWithPrivateFields() { + super(); + } + + public UserWithPrivateFields(final int id, final String name) { + this.id = id; + this.name = name; + } + +} diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithRoot.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithRoot.java new file mode 100644 index 0000000000..cadcd43a72 --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/UserWithRoot.java @@ -0,0 +1,18 @@ +package com.baeldung.exceptions; + +import com.fasterxml.jackson.annotation.JsonRootName; + +@JsonRootName(value = "user") +public class UserWithRoot { + public int id; + public String name; + + public UserWithRoot() { + super(); + } + + public UserWithRoot(final int id, final String name) { + this.id = id; + this.name = name; + } +} diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/Zoo.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/Zoo.java new file mode 100644 index 0000000000..3e729a1d2f --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/Zoo.java @@ -0,0 +1,22 @@ +package com.baeldung.exceptions; + +public class Zoo { + public Animal animal; + + public Zoo() { + } +} + +abstract class Animal { + public String name; + + public Animal() { + } +} + +class Cat extends Animal { + public int lives; + + public Cat() { + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/ZooConfigured.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/ZooConfigured.java new file mode 100644 index 0000000000..31c2ce4d4c --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/exceptions/ZooConfigured.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class ZooConfigured { + public AnimalConfigured animal; + + public ZooConfigured() { + } +} + +@JsonDeserialize(as = CatConfigured.class) +abstract class AnimalConfigured { + public String name; + + public AnimalConfigured() { + } +} + +class CatConfigured extends AnimalConfigured { + public int lives; + + public CatConfigured() { + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessors.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessors.java new file mode 100644 index 0000000000..17bc5257fb --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessors.java @@ -0,0 +1,21 @@ +package com.baeldung.mappingexception; + +public class MyDtoNoAccessors { + + String stringValue; + int intValue; + boolean booleanValue; + + public MyDtoNoAccessors() { + super(); + } + + public MyDtoNoAccessors(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + +} diff --git a/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessorsAndFieldVisibility.java b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessorsAndFieldVisibility.java new file mode 100644 index 0000000000..cf5d5ca500 --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/main/java/com/baeldung/mappingexception/MyDtoNoAccessorsAndFieldVisibility.java @@ -0,0 +1,25 @@ +package com.baeldung.mappingexception; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; + +@JsonAutoDetect(fieldVisibility = Visibility.ANY) +public class MyDtoNoAccessorsAndFieldVisibility { + + String stringValue; + int intValue; + boolean booleanValue; + + public MyDtoNoAccessorsAndFieldVisibility() { + super(); + } + + public MyDtoNoAccessorsAndFieldVisibility(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + +} diff --git a/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java new file mode 100644 index 0000000000..38ef3f9390 --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java @@ -0,0 +1,195 @@ +package com.baeldung.exceptions; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +import com.baeldung.exceptions.User; +import com.baeldung.exceptions.UserWithPrivateFields; +import com.baeldung.exceptions.UserWithRoot; +import com.baeldung.exceptions.Zoo; +import com.baeldung.exceptions.ZooConfigured; +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; + +public class JacksonExceptionsUnitTest { + + // JsonMappingException: Can not construct instance of + @Test(expected = JsonMappingException.class) + public void givenAbstractClass_whenDeserializing_thenException() throws IOException { + final String json = "{\"animal\":{\"name\":\"lacy\"}}"; + final ObjectMapper mapper = new ObjectMapper(); + + mapper.reader() + .forType(Zoo.class) + .readValue(json); + } + + @Test + public void givenAbstractClassConfigured_whenDeserializing_thenCorrect() throws IOException { + final String json = "{\"animal\":{\"name\":\"lacy\"}}"; + final ObjectMapper mapper = new ObjectMapper(); + + mapper.reader() + .forType(ZooConfigured.class) + .readValue(json); + } + + // JsonMappingException: No serializer found for class + @Test(expected = JsonMappingException.class) + public void givenClassWithPrivateFields_whenSerializing_thenException() throws IOException { + final UserWithPrivateFields user = new UserWithPrivateFields(1, "John"); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.writer() + .writeValueAsString(user); + } + + @Test + public void givenClassWithPrivateFields_whenConfigureSerializing_thenCorrect() throws IOException { + final UserWithPrivateFields user = new UserWithPrivateFields(1, "John"); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + + final String result = mapper.writer() + .writeValueAsString(user); + assertThat(result, containsString("John")); + } + + // JsonMappingException: No suitable constructor found + @Test(expected = JsonMappingException.class) + public void givenNoDefaultConstructor_whenDeserializing_thenException() throws IOException { + final String json = "{\"id\":1,\"name\":\"John\"}"; + final ObjectMapper mapper = new ObjectMapper(); + + mapper.reader() + .forType(UserWithNoDefaultConstructor.class) + .readValue(json); + } + + @Test + public void givenDefaultConstructor_whenDeserializing_thenCorrect() throws IOException { + final String json = "{\"id\":1,\"name\":\"John\"}"; + final ObjectMapper mapper = new ObjectMapper(); + + final User user = mapper.reader() + .forType(User.class) + .readValue(json); + assertEquals("John", user.name); + } + + // JsonMappingException: Root name does not match expected + @Test(expected = JsonMappingException.class) + public void givenWrappedJsonString_whenDeserializing_thenException() throws IOException { + final String json = "{\"user\":{\"id\":1,\"name\":\"John\"}}"; + + final ObjectMapper mapper = new ObjectMapper(); + mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); + + mapper.reader() + .forType(User.class) + .readValue(json); + } + + @Test + public void givenWrappedJsonStringAndConfigureClass_whenDeserializing_thenCorrect() throws IOException { + final String json = "{\"user\":{\"id\":1,\"name\":\"John\"}}"; + + final ObjectMapper mapper = new ObjectMapper(); + mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); + + final UserWithRoot user = mapper.reader() + .forType(UserWithRoot.class) + .readValue(json); + assertEquals("John", user.name); + } + + // JsonMappingException: Can not deserialize instance of + @Test(expected = JsonMappingException.class) + public void givenJsonOfArray_whenDeserializing_thenException() throws JsonProcessingException, IOException { + final String json = "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]"; + final ObjectMapper mapper = new ObjectMapper(); + + mapper.reader() + .forType(User.class) + .readValue(json); + } + + @Test + public void givenJsonOfArray_whenDeserializing_thenCorrect() throws JsonProcessingException, IOException { + final String json = "[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Adam\"}]"; + final ObjectMapper mapper = new ObjectMapper(); + + final List users = mapper.reader() + .forType(new TypeReference>() { + }) + .readValue(json); + + assertEquals(2, users.size()); + } + + // UnrecognizedPropertyException + @Test(expected = UnrecognizedPropertyException.class) + public void givenJsonStringWithExtra_whenDeserializing_thenException() throws IOException { + final String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}"; + + final ObjectMapper mapper = new ObjectMapper(); + mapper.reader() + .forType(User.class) + .readValue(json); + } + + @Test + public void givenJsonStringWithExtra_whenConfigureDeserializing_thenCorrect() throws IOException { + final String json = "{\"id\":1,\"name\":\"John\", \"checked\":true}"; + + final ObjectMapper mapper = new ObjectMapper(); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + final User user = mapper.reader() + .forType(User.class) + .readValue(json); + assertEquals("John", user.name); + } + + // JsonParseException: Unexpected character (''' (code 39)) + @Test(expected = JsonParseException.class) + public void givenStringWithSingleQuotes_whenDeserializing_thenException() throws JsonProcessingException, IOException { + final String json = "{'id':1,'name':'John'}"; + final ObjectMapper mapper = new ObjectMapper(); + + mapper.reader() + .forType(User.class) + .readValue(json); + } + + @Test + public void givenStringWithSingleQuotes_whenConfigureDeserializing_thenCorrect() throws JsonProcessingException, IOException { + final String json = "{'id':1,'name':'John'}"; + + final JsonFactory factory = new JsonFactory(); + factory.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES); + final ObjectMapper mapper = new ObjectMapper(factory); + + final User user = mapper.reader() + .forType(User.class) + .readValue(json); + assertEquals("John", user.name); + } + +} diff --git a/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java new file mode 100644 index 0000000000..df35626828 --- /dev/null +++ b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/mappingexception/JacksonMappingExceptionUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.mappingexception; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.List; +import org.junit.Test; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +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.module.SimpleModule; +import com.google.common.collect.Lists; + +public class JacksonMappingExceptionUnitTest { + + @Test(expected = JsonMappingException.class) + public final void givenObjectHasNoAccessors_whenSerializing_thenException() throws JsonParseException, IOException { + final String dtoAsString = new ObjectMapper().writeValueAsString(new MyDtoNoAccessors()); + + assertThat(dtoAsString, notNullValue()); + } + + @Test + public final void givenObjectHasNoAccessors_whenSerializingWithPrivateFieldsVisibility_thenNoException() throws JsonParseException, IOException { + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + final String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessors()); + + assertThat(dtoAsString, containsString("intValue")); + assertThat(dtoAsString, containsString("stringValue")); + assertThat(dtoAsString, containsString("booleanValue")); + } + + @Test + public final void givenObjectHasNoAccessorsButHasVisibleFields_whenSerializing_thenNoException() throws JsonParseException, IOException { + final ObjectMapper objectMapper = new ObjectMapper(); + final String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessorsAndFieldVisibility()); + + assertThat(dtoAsString, containsString("intValue")); + assertThat(dtoAsString, containsString("stringValue")); + assertThat(dtoAsString, containsString("booleanValue")); + } + +} diff --git a/jackson-modules/pom.xml b/jackson-modules/pom.xml new file mode 100644 index 0000000000..69ac41998d --- /dev/null +++ b/jackson-modules/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + jackson-modules + jackson-modules + pom + + + com.ossez + parent-java + 0.0.2-SNAPSHOT + ../parent-java + + + + jackson + jackson-annotations + jackson-conversions + jackson-conversions-2 + jackson-custom-conversions + jackson-exceptions + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson.version} + + + org.junit.jupiter + junit-jupiter + ${junit-jupiter.version} + + + + org.junit.vintage + junit-vintage-engine + ${junit-jupiter.version} + test + + + + + 5.6.2 + + + \ No newline at end of file