diff --git a/jackson/pom.xml b/jackson/pom.xml
index 53fb82c61e..2300208605 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -67,6 +67,12 @@
${jackson.version}
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+ ${jackson.version}
+
+
joda-time
joda-time
@@ -128,8 +134,8 @@
${mockito.version}
test
-
-
+
+
org.slf4j
@@ -152,7 +158,7 @@
org.slf4j
log4j-over-slf4j
${org.slf4j.version}
-
+
@@ -198,7 +204,7 @@
19.0
3.5
- 2.5
+ 2.5
2.9.6
2.8.0
4.1
diff --git a/jackson/src/main/java/com/baeldung/jackson/miscellaneous/mixin/Book.java b/jackson/src/main/java/com/baeldung/jackson/miscellaneous/mixin/Book.java
new file mode 100644
index 0000000000..fb961efe85
--- /dev/null
+++ b/jackson/src/main/java/com/baeldung/jackson/miscellaneous/mixin/Book.java
@@ -0,0 +1,25 @@
+package com.baeldung.jackson.miscellaneous.mixin;
+
+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/src/test/java/com/baeldung/jackson/miscellaneous/mixin/OptionalTypeTest.java b/jackson/src/test/java/com/baeldung/jackson/miscellaneous/mixin/OptionalTypeTest.java
new file mode 100644
index 0000000000..035c65f846
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/miscellaneous/mixin/OptionalTypeTest.java
@@ -0,0 +1,74 @@
+package com.baeldung.jackson.miscellaneous.mixin;
+
+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 OptionalTypeTest {
+
+ ObjectMapper mapper = new ObjectMapper()
+ .registerModule(new Jdk8Module());
+
+ @Test
+ public void givenOptional_whenSerializing_thenValueInJson() throws JsonProcessingException {
+
+ // arrange
+ String subTitle = "The Parish Boy's Progress";
+ Book book = new Book();
+ book.setTitle("Oliver Twist");
+ book.setSubTitle(Optional.of(subTitle));
+
+ // act
+ String result = mapper.writeValueAsString(book);
+
+ // assert
+ assertThat(from(result).getString("subTitle")).isEqualTo(subTitle);
+ }
+
+ @Test
+ public void givenEmptyOptional_whenSerializing_thenNullValue() throws JsonProcessingException {
+
+ // arrange
+ Book book = new Book();
+ book.setTitle("Oliver Twist");
+ book.setSubTitle(Optional.empty());
+
+ // act
+ String result = mapper.writeValueAsString(book);
+
+ // assert
+ assertThat(from(result).getString("subTitle")).isNull();
+ }
+
+ @Test
+ public void givenField_whenDeserializing_thenOptionalWithValue() throws IOException {
+
+ // arrange
+ String subTitle = "The Parish Boy's Progress";
+ String book = "{ \"title\": \"Oliver Twist\", \"subTitle\": \"" + subTitle + "\" }";
+
+ // act
+ Book result = mapper.readValue(book, Book.class);
+
+ // assert
+ assertThat(result.getSubTitle()).isEqualTo(Optional.of(subTitle));
+ }
+
+ @Test
+ public void givenEmptyField_whenDeserializing_thenEmptyOptional() throws IOException {
+
+ // arrange
+ String book = "{ \"title\": \"Oliver Twist\", \"subTitle\": null }";
+
+ // act
+ Book result = mapper.readValue(book, Book.class);
+
+ // assert
+ assertThat(result.getSubTitle()).isEmpty();
+ }
+}