diff --git a/jackson-modules/jackson-core-3/pom.xml b/jackson-modules/jackson-core-3/pom.xml new file mode 100644 index 000000000000..1db7aa89a819 --- /dev/null +++ b/jackson-modules/jackson-core-3/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + com.baeldung + jackson-modules + 0.0.1-SNAPSHOT + + + jackson-core-3 + + + 3.2.1 + + + + + tools.jackson.core + jackson-databind + ${jackson3.version} + + + + tools.jackson.dataformat + jackson-dataformat-xml + ${jackson3.version} + + + + \ No newline at end of file diff --git a/jackson-modules/jackson-core-3/src/main/java/com/baeldung/jackson/whatsnew/MapperFactory.java b/jackson-modules/jackson-core-3/src/main/java/com/baeldung/jackson/whatsnew/MapperFactory.java new file mode 100644 index 000000000000..05e9c01199b9 --- /dev/null +++ b/jackson-modules/jackson-core-3/src/main/java/com/baeldung/jackson/whatsnew/MapperFactory.java @@ -0,0 +1,24 @@ +package com.baeldung.jackson.whatsnew; + +import tools.jackson.core.json.JsonWriteFeature; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.cfg.DateTimeFeature; +import tools.jackson.databind.json.JsonMapper; + +public class MapperFactory { + + public static JsonMapper getMapper() { + return JsonMapper.builder() + .enable(SerializationFeature.INDENT_OUTPUT) + .disable(JsonWriteFeature.ESCAPE_NON_ASCII) + .configure(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .build(); + } + + public static JsonMapper rebuildPretty(JsonMapper jsonMapper) { + return jsonMapper.rebuild() + .enable(SerializationFeature.INDENT_OUTPUT) + .build(); + } + +} diff --git a/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/DefaultBehaviorTest.java b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/DefaultBehaviorTest.java new file mode 100644 index 000000000000..3592a2b74d5f --- /dev/null +++ b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/DefaultBehaviorTest.java @@ -0,0 +1,23 @@ +package com.baeldung.jackson.whatsnew; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultBehaviorTest { + + @Test + void givenJsonWithAdditionalField_whenReadValue_thenSuccessWithoutUnknownField() { + var json = "{\"name\":\"Alice\", \"unknownField\":\"ignored_value\"}"; + var mapper = MapperFactory.getMapper(); + + var user = mapper.readValue(json, User.class); + + assertThat(user) + .returns("Alice", User::name); + } + + private record User(String name) {} +} diff --git a/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/Java8FeaturesTest.java b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/Java8FeaturesTest.java new file mode 100644 index 000000000000..53ed2650045c --- /dev/null +++ b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/Java8FeaturesTest.java @@ -0,0 +1,32 @@ +package com.baeldung.jackson.whatsnew; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +public class Java8FeaturesTest { + + @Test + void givenJava8TypesAndNoConfiguration_whenWriteValueAsString_thenSuccess() { + var now = LocalDateTime.now(); + var event = new Event("Tech Talk", Optional.of("Jackson 3 overview"), now); + var mapper = MapperFactory.getMapper(); + + var json = mapper.writeValueAsString(event); + assertThat(json) + .isEqualTo(""" + { + "title" : "Tech Talk", + "description" : "Jackson 3 overview", + "eventDate" : "" + }""".replace("", now.toString())); + var deserialized = mapper.readValue(json, Event.class); + assertThat(deserialized) + .isEqualTo(event); + } + + private record Event(String title, Optional description, LocalDateTime eventDate) {} +} diff --git a/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/JsonNodeTest.java b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/JsonNodeTest.java new file mode 100644 index 000000000000..9c0597b41ca3 --- /dev/null +++ b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/JsonNodeTest.java @@ -0,0 +1,24 @@ +package com.baeldung.jackson.whatsnew; + +import org.junit.jupiter.api.Test; + +import java.util.OptionalInt; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JsonNodeTest { + + @Test + void givenJson_whenReadTree_thenValueAccessorEnhanced() { + var json = "{\"product\":\"Laptop\",\"price\":1200}"; + var root = MapperFactory.getMapper().readTree(json); + + var product = root.get("product").asString(); + var price = root.get("price").intValueOpt(); + + assertThat(product) + .isEqualTo("Laptop"); + assertThat(price) + .isEqualTo(OptionalInt.of(1200)); + } +} diff --git a/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/MapperFactoryTest.java b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/MapperFactoryTest.java new file mode 100644 index 000000000000..1d7e326377f8 --- /dev/null +++ b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/MapperFactoryTest.java @@ -0,0 +1,27 @@ +package com.baeldung.jackson.whatsnew; + +import org.junit.jupiter.api.Test; +import tools.jackson.databind.SerializationFeature; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; + +class MapperFactoryTest { + + @Test + void whenGetMapper_thenSuccess() { + assertThatNoException().isThrownBy(MapperFactory::getMapper); + } + + @Test + void givenMapper_whenRebuildPretty_thenSuccess() { + var mapper = MapperFactory.getMapper(); + + var prettyMapper = MapperFactory.rebuildPretty(mapper); + + assertThat(prettyMapper) + .isNotNull() + .isNotSameAs(mapper) + .returns(true, m -> m.isEnabled(SerializationFeature.INDENT_OUTPUT)); + } +} \ No newline at end of file diff --git a/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/UncheckedExceptionTest.java b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/UncheckedExceptionTest.java new file mode 100644 index 000000000000..eec599f78101 --- /dev/null +++ b/jackson-modules/jackson-core-3/src/test/java/com/baeldung/jackson/whatsnew/UncheckedExceptionTest.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.whatsnew; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UncheckedExceptionTest { + + @Test + void givenMapperAndUserRecord_whenReadValue_thenSuccessNoTryCatchNeeded() { + var jsonPayloads = List.of("{\"name\":\"Matt\"}", "{\"name\":\"Jack\"}"); + var mapper = MapperFactory.getMapper(); + + var users = jsonPayloads.stream() + .map(json -> mapper.readValue(json, User.class)) + .toList(); + + assertThat(users) + .hasSize(2) + .containsExactlyInAnyOrder(new User("Matt"), new User("Jack")); + } + + private record User(String name) {} +} diff --git a/jackson-modules/pom.xml b/jackson-modules/pom.xml index 4272aae76e9c..06284fca8c27 100644 --- a/jackson-modules/pom.xml +++ b/jackson-modules/pom.xml @@ -26,6 +26,7 @@ jackson-exceptions jackson-jr jackson-polymorphic-deserialization + jackson-core-3