diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy
new file mode 100644
index 0000000000..eb4d1f7f87
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy
@@ -0,0 +1,3 @@
+package com.baeldung
+
+class Car implements VehicleTrait {}
\ No newline at end of file
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy
index 3f1e694f17..0d395bffcd 100644
--- a/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy
+++ b/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy
@@ -22,7 +22,7 @@ trait UserTrait implements Human {
msg
}
- def whoAmI() {
+ def self() {
return this
}
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy
new file mode 100644
index 0000000000..f5ae8fab30
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy
@@ -0,0 +1,9 @@
+package com.baeldung
+
+trait VehicleTrait extends WheelTrait {
+
+ String showWheels() {
+ return "Num of Wheels $noOfWheels"
+ }
+
+}
\ No newline at end of file
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy
new file mode 100644
index 0000000000..364d5b883e
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy
@@ -0,0 +1,7 @@
+package com.baeldung
+
+trait WheelTrait {
+
+ int noOfWheels
+
+}
\ No newline at end of file
diff --git a/core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy b/core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy
new file mode 100644
index 0000000000..97ffc50c76
--- /dev/null
+++ b/core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy
@@ -0,0 +1,85 @@
+package com.baeldung.map
+
+import static org.junit.Assert.*
+import org.junit.Test
+
+class MapUnitTest {
+
+ @Test
+ void whenUsingEach_thenMapIsIterated() {
+ def map = [
+ 'FF0000' : 'Red',
+ '00FF00' : 'Lime',
+ '0000FF' : 'Blue',
+ 'FFFF00' : 'Yellow'
+ ]
+
+ map.each { println "Hex Code: $it.key = Color Name: $it.value" }
+ }
+
+ @Test
+ void whenUsingEachWithEntry_thenMapIsIterated() {
+ def map = [
+ 'E6E6FA' : 'Lavender',
+ 'D8BFD8' : 'Thistle',
+ 'DDA0DD' : 'Plum',
+ ]
+
+ map.each { entry -> println "Hex Code: $entry.key = Color Name: $entry.value" }
+ }
+
+ @Test
+ void whenUsingEachWithKeyAndValue_thenMapIsIterated() {
+ def map = [
+ '000000' : 'Black',
+ 'FFFFFF' : 'White',
+ '808080' : 'Gray'
+ ]
+
+ map.each { key, val ->
+ println "Hex Code: $key = Color Name $val"
+ }
+ }
+
+ @Test
+ void whenUsingEachWithIndexAndEntry_thenMapIsIterated() {
+ def map = [
+ '800080' : 'Purple',
+ '4B0082' : 'Indigo',
+ '6A5ACD' : 'Slate Blue'
+ ]
+
+ map.eachWithIndex { entry, index ->
+ def indent = ((index == 0 || index % 2 == 0) ? " " : "")
+ println "$indent Hex Code: $entry.key = Color Name: $entry.value"
+ }
+ }
+
+ @Test
+ void whenUsingEachWithIndexAndKeyAndValue_thenMapIsIterated() {
+ def map = [
+ 'FFA07A' : 'Light Salmon',
+ 'FF7F50' : 'Coral',
+ 'FF6347' : 'Tomato',
+ 'FF4500' : 'Orange Red'
+ ]
+
+ map.eachWithIndex { key, val, index ->
+ def indent = ((index == 0 || index % 2 == 0) ? " " : "")
+ println "$indent Hex Code: $key = Color Name: $val"
+ }
+ }
+
+ @Test
+ void whenUsingForLoop_thenMapIsIterated() {
+ def map = [
+ '2E8B57' : 'Seagreen',
+ '228B22' : 'Forest Green',
+ '008000' : 'Green'
+ ]
+
+ for (entry in map) {
+ println "Hex Code: $entry.key = Color Name: $entry.value"
+ }
+ }
+}
diff --git a/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy b/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy
index 0c74a9be62..85130e8f07 100644
--- a/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy
+++ b/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy
@@ -57,7 +57,7 @@ class TraitsUnitTest extends Specification {
def 'Should return employee instance when using Employee.whoAmI method' () {
when:
- def emp = employee.whoAmI()
+ def emp = employee.self()
then:
emp
emp instanceof Employee
diff --git a/core-java-collections-list/README.md b/core-java-collections-list/README.md
index d1112047ba..3a4a7c69e8 100644
--- a/core-java-collections-list/README.md
+++ b/core-java-collections-list/README.md
@@ -27,3 +27,4 @@
- [Flattening Nested Collections in Java](http://www.baeldung.com/java-flatten-nested-collections)
- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection)
- [Multi Dimensional ArrayList in Java](https://www.baeldung.com/java-multi-dimensional-arraylist)
+- [Determine If All Elements Are the Same in a Java List](https://www.baeldung.com/java-list-all-equal)
diff --git a/core-java-collections-list/pom.xml b/core-java-collections-list/pom.xml
index 737be8ee34..b9b6f4a6a6 100644
--- a/core-java-collections-list/pom.xml
+++ b/core-java-collections-list/pom.xml
@@ -52,6 +52,17 @@
colt
${colt.version}
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh-core.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh-core.version}
+
diff --git a/core-java-collections-list/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java b/core-java-collections-list/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java
new file mode 100644
index 0000000000..bd37e5e74e
--- /dev/null
+++ b/core-java-collections-list/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java
@@ -0,0 +1,96 @@
+package com.baeldung.list.primitive;
+
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import gnu.trove.list.array.TIntArrayList;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.SingleShotTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Measurement(batchSize = 100000, iterations = 10)
+@Warmup(batchSize = 100000, iterations = 10)
+@State(Scope.Thread)
+public class PrimitivesListPerformance {
+
+ private List arrayList = new ArrayList<>();
+ private TIntArrayList tList = new TIntArrayList();
+ private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList();
+ private IntArrayList fastUtilList = new IntArrayList();
+
+ private int getValue = 10;
+
+ @Benchmark
+ public boolean addArrayList() {
+ return arrayList.add(getValue);
+ }
+
+ @Benchmark
+ public boolean addTroveIntList() {
+ return tList.add(getValue);
+ }
+
+ @Benchmark
+ public void addColtIntList() {
+ coltList.add(getValue);
+ }
+
+ @Benchmark
+ public boolean addFastUtilIntList() {
+ return fastUtilList.add(getValue);
+ }
+
+ @Benchmark
+ public int getArrayList() {
+ return arrayList.get(getValue);
+ }
+
+ @Benchmark
+ public int getTroveIntList() {
+ return tList.get(getValue);
+ }
+
+ @Benchmark
+ public int getColtIntList() {
+ return coltList.get(getValue);
+ }
+
+ @Benchmark
+ public int getFastUtilIntList() {
+ return fastUtilList.getInt(getValue);
+ }
+
+ @Benchmark
+ public boolean containsArrayList() {
+ return arrayList.contains(getValue);
+ }
+
+ @Benchmark
+ public boolean containsTroveIntList() {
+ return tList.contains(getValue);
+ }
+
+ @Benchmark
+ public boolean containsColtIntList() {
+ return coltList.contains(getValue);
+ }
+
+ @Benchmark
+ public boolean containsFastUtilIntList() {
+ return fastUtilList.contains(getValue);
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder()
+ .include(PrimitivesListPerformance.class.getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/gson/src/test/java/org/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java b/gson/src/test/java/org/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java
new file mode 100644
index 0000000000..847ec1b85d
--- /dev/null
+++ b/gson/src/test/java/org/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java
@@ -0,0 +1,33 @@
+package org.baeldung.gson.conversion;
+
+import com.google.gson.*;
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+
+public class JsonObjectConversionsUnitTest {
+
+ @Test
+ void whenUsingJsonParser_thenConvertToJsonObject() throws Exception {
+ // Example 1: Using JsonParser
+ String json = "{ \"name\": \"Baeldung\", \"java\": true }";
+
+ JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
+
+ Assert.assertTrue(jsonObject.isJsonObject());
+ Assert.assertTrue(jsonObject.get("name").getAsString().equals("Baeldung"));
+ Assert.assertTrue(jsonObject.get("java").getAsBoolean() == true);
+ }
+
+ @Test
+ void whenUsingGsonInstanceFromJson_thenConvertToJsonObject() throws Exception {
+ // Example 2: Using fromJson
+ String json = "{ \"name\": \"Baeldung\", \"java\": true }";
+
+ JsonObject convertedObject = new Gson().fromJson(json, JsonObject.class);
+
+ Assert.assertTrue(convertedObject.isJsonObject());
+ Assert.assertTrue(convertedObject.get("name").getAsString().equals("Baeldung"));
+ Assert.assertTrue(convertedObject.get("java").getAsBoolean() == true);
+ }
+
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java b/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java
index 19e7d4c53c..985851f456 100644
--- a/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java
+++ b/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java
@@ -1,16 +1,9 @@
package com.baeldung.jackson.dtos;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-
public class Address {
- @JacksonXmlProperty(localName = "street_number")
String streetNumber;
-
- @JacksonXmlProperty(localName = "street_name")
String streetName;
-
- @JacksonXmlProperty(localName = "city")
String city;
public String getStreetNumber() {
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java b/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java
index 7891595cc6..13093cdcad 100644
--- a/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java
+++ b/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java
@@ -3,16 +3,13 @@ package com.baeldung.jackson.dtos;
import java.util.ArrayList;
import java.util.List;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
@JacksonXmlRootElement(localName = "person")
public final class Person {
private String firstName;
private String lastName;
- @JacksonXmlElementWrapper(useWrapping = false)
private List phoneNumbers = new ArrayList<>();
- @JacksonXmlElementWrapper(localName = "addresses")
private List address = new ArrayList<>();
public List getAddress() {
@@ -38,6 +35,7 @@ public final class Person {
public void setLastName(String lastName) {
this.lastName = lastName;
}
+
public List getPhoneNumbers() {
return phoneNumbers;
}
@@ -46,6 +44,4 @@ public final class Person {
this.phoneNumbers = phoneNumbers;
}
-
-
}
\ No newline at end of file
diff --git a/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java
index 039edd45bc..1d430e9758 100644
--- a/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java
@@ -2,8 +2,10 @@ package com.baeldung.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;
@@ -56,17 +58,14 @@ public class XMLSerializeDeserializeUnitTest {
@Test
public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
- SimpleBeanForCapitalizedFields value = xmlMapper.
- readValue("12",
- SimpleBeanForCapitalizedFields.class);
+ 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());
+ xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"), new SimpleBeanForCapitalizedFields());
File file = new File("target/simple_bean_capitalized.xml");
assertNotNull(file);
}
@@ -74,7 +73,9 @@ public class XMLSerializeDeserializeUnitTest {
@Test
public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
- Person value = xmlMapper.readValue(new File("src/test/resources/person.xml"), Person.class);
+
+ String xml = "RohanDaye991103473199110334781Name1City12Name2City2";
+ Person value = xmlMapper.readValue(xml, Person.class);
assertTrue(value.getAddress()
.get(0)
@@ -90,33 +91,38 @@ public class XMLSerializeDeserializeUnitTest {
public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException {
XmlMapper xmlMapper = new XmlMapper();
+ String expectedXml = "RohanDaye991103473199110334781Name1City12Name2City2";
+
Person person = new Person();
person.setFirstName("Rohan");
person.setLastName("Daye");
List ph = new ArrayList<>();
- ph.add("9911778981");
- ph.add("9991111111");
+ ph.add("9911034731");
+ ph.add("9911033478");
person.setPhoneNumbers(ph);
List addresses = new ArrayList<>();
-
+
Address address1 = new Address();
address1.setStreetNumber("1");
- address1.setStreetName("streetname1");
- address1.setCity("city1");
-
+ address1.setStreetName("Name1");
+ address1.setCity("City1");
+
Address address2 = new Address();
address2.setStreetNumber("2");
- address2.setStreetName("streetname2");
- address2.setCity("city2");
-
+ address2.setStreetName("Name2");
+ address2.setCity("City2");
+
addresses.add(address1);
addresses.add(address2);
+
person.setAddress(addresses);
- xmlMapper.writeValue(new File("src/test/resources/PersonGenerated.xml"), person);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ xmlMapper.writeValue(byteArrayOutputStream, person);
+ assertEquals(expectedXml, byteArrayOutputStream.toString());
}
private static String inputStreamToString(InputStream is) throws IOException {
diff --git a/jackson/src/test/resources/PersonGenerated.xml b/jackson/src/test/resources/PersonGenerated.xml
deleted file mode 100644
index 6ebadd971a..0000000000
--- a/jackson/src/test/resources/PersonGenerated.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- 9911778981
- 9991111111
-
-
- 1
- streetname1
- city1
-
-
- 2
- streetname2
- city2
-
-
-
\ No newline at end of file
diff --git a/jackson/src/test/resources/person.xml b/jackson/src/test/resources/person.xml
deleted file mode 100644
index 39a6e859c4..0000000000
--- a/jackson/src/test/resources/person.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
- Rohan
- Daye
- 9911034731
- 9911033478
-
-
- 1
- Name1
- City1
-
-
- 2
- Name2
- City2
-
-
-
\ No newline at end of file
diff --git a/json/pom.xml b/json/pom.xml
index 23955e5a75..7a6d57c28e 100644
--- a/json/pom.xml
+++ b/json/pom.xml
@@ -73,6 +73,12 @@
${commons-collections4.version}
test
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+ test
+
@@ -86,6 +92,7 @@
2.9.7
4.12
1.1.2
+ 3.11.1
diff --git a/json/src/main/java/com/baeldung/jsonobject/iterate/JSONObjectIterator.java b/json/src/main/java/com/baeldung/jsonobject/iterate/JSONObjectIterator.java
new file mode 100644
index 0000000000..0ff8650652
--- /dev/null
+++ b/json/src/main/java/com/baeldung/jsonobject/iterate/JSONObjectIterator.java
@@ -0,0 +1,50 @@
+package com.baeldung.jsonobject.iterate;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public class JSONObjectIterator {
+
+ private Map keyValuePairs;
+
+ public JSONObjectIterator() {
+ keyValuePairs = new HashMap<>();
+ }
+
+ public void handleValue(String key, Object value) {
+ if (value instanceof JSONArray) {
+ handleJSONArray(key, (JSONArray) value);
+ } else if (value instanceof JSONObject) {
+ handleJSONObject((JSONObject) value);
+ }
+ keyValuePairs.put(key, value);
+ }
+
+ public void handleJSONObject(JSONObject jsonObject) {
+ Iterator jsonObjectIterator = jsonObject.keys();
+ jsonObjectIterator.forEachRemaining(key -> {
+ Object value = jsonObject.get(key);
+ handleValue(key, value);
+ });
+ }
+
+ public void handleJSONArray(String key, JSONArray jsonArray) {
+ Iterator
diff --git a/spring-boot-data/README.md b/spring-boot-data/README.md
new file mode 100644
index 0000000000..21f7303c48
--- /dev/null
+++ b/spring-boot-data/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Formatting JSON Dates in Spring ](https://www.baeldung.com/spring-boot-formatting-json-dates)
\ No newline at end of file
diff --git a/spring-boot-data/pom.xml b/spring-boot-data/pom.xml
new file mode 100644
index 0000000000..9ef4cc69c8
--- /dev/null
+++ b/spring-boot-data/pom.xml
@@ -0,0 +1,122 @@
+
+
+ 4.0.0
+ spring-boot-data
+ war
+ spring-boot-data
+ Spring Boot Data Module
+
+
+ parent-boot-2
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ spring-boot
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+ pl.project13.maven
+ git-commit-id-plugin
+ ${git-commit-id-plugin.version}
+
+
+ get-the-git-infos
+
+ revision
+
+ initialize
+
+
+ validate-the-git-infos
+
+ validateRevision
+
+ package
+
+
+
+ true
+ ${project.build.outputDirectory}/git.properties
+
+
+
+
+
+
+
+
+ autoconfiguration
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*LiveTest.java
+ **/*IntegrationTest.java
+ **/*IntTest.java
+
+
+ **/AutoconfigurationTest.java
+
+
+
+
+
+
+ json
+
+
+
+
+
+
+
+
+
+ com.baeldung.SpringBootDataApplication
+ 2.2.4
+
+
+
\ No newline at end of file
diff --git a/spring-boot-data/src/main/java/com/baeldung/SpringBootDataApplication.java b/spring-boot-data/src/main/java/com/baeldung/SpringBootDataApplication.java
new file mode 100644
index 0000000000..3aa093bb41
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/SpringBootDataApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootDataApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootDataApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/Contact.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/Contact.java
new file mode 100644
index 0000000000..f131d17196
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/Contact.java
@@ -0,0 +1,70 @@
+package com.baeldung.jsondateformat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+public class Contact {
+
+ private String name;
+ private String address;
+ private String phone;
+
+ @JsonFormat(pattern="yyyy-MM-dd")
+ private LocalDate birthday;
+
+ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime lastUpdate;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public LocalDate getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(LocalDate birthday) {
+ this.birthday = birthday;
+ }
+
+ public LocalDateTime getLastUpdate() {
+ return lastUpdate;
+ }
+
+ public void setLastUpdate(LocalDateTime lastUpdate) {
+ this.lastUpdate = lastUpdate;
+ }
+
+ public Contact() {
+ }
+
+ public Contact(String name, String address, String phone, LocalDate birthday, LocalDateTime lastUpdate) {
+ this.name = name;
+ this.address = address;
+ this.phone = phone;
+ this.birthday = birthday;
+ this.lastUpdate = lastUpdate;
+ }
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactApp.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactApp.java
new file mode 100644
index 0000000000..79037e1038
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactApp.java
@@ -0,0 +1,13 @@
+package com.baeldung.jsondateformat;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ContactApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ContactApp.class, args);
+ }
+
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactAppConfig.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactAppConfig.java
new file mode 100644
index 0000000000..7a20ebfa51
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactAppConfig.java
@@ -0,0 +1,33 @@
+package com.baeldung.jsondateformat;
+
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+
+import java.time.format.DateTimeFormatter;
+
+@Configuration
+public class ContactAppConfig {
+
+ private static final String dateFormat = "yyyy-MM-dd";
+
+ private static final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
+
+ @Bean
+ @ConditionalOnProperty(value = "spring.jackson.date-format", matchIfMissing = true, havingValue = "none")
+ public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
+ return new Jackson2ObjectMapperBuilderCustomizer() {
+ @Override
+ public void customize(Jackson2ObjectMapperBuilder builder) {
+ builder.simpleDateFormat(dateTimeFormat);
+ builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
+ builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat)));
+ }
+ };
+ }
+
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactController.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactController.java
new file mode 100644
index 0000000000..8894d82fc7
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactController.java
@@ -0,0 +1,77 @@
+package com.baeldung.jsondateformat;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/contacts")
+public class ContactController {
+
+ @GetMapping
+ public List getContacts() {
+ List contacts = new ArrayList<>();
+
+ Contact contact1 = new Contact("John Doe", "123 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now());
+ Contact contact2 = new Contact("John Doe 2", "124 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now());
+ Contact contact3 = new Contact("John Doe 3", "125 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now());
+
+ contacts.add(contact1);
+ contacts.add(contact2);
+ contacts.add(contact3);
+
+ return contacts;
+ }
+
+ @GetMapping("/javaUtilDate")
+ public List getContactsWithJavaUtilDate() {
+ List contacts = new ArrayList<>();
+
+ ContactWithJavaUtilDate contact1 = new ContactWithJavaUtilDate("John Doe", "123 Sesame Street", "123-456-789", new Date(), new Date());
+ ContactWithJavaUtilDate contact2 = new ContactWithJavaUtilDate("John Doe 2", "124 Sesame Street", "123-456-789", new Date(), new Date());
+ ContactWithJavaUtilDate contact3 = new ContactWithJavaUtilDate("John Doe 3", "125 Sesame Street", "123-456-789", new Date(), new Date());
+
+ contacts.add(contact1);
+ contacts.add(contact2);
+ contacts.add(contact3);
+
+ return contacts;
+ }
+
+ @GetMapping("/plain")
+ public List getPlainContacts() {
+ List contacts = new ArrayList<>();
+
+ PlainContact contact1 = new PlainContact("John Doe", "123 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now());
+ PlainContact contact2 = new PlainContact("John Doe 2", "124 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now());
+ PlainContact contact3 = new PlainContact("John Doe 3", "125 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now());
+
+ contacts.add(contact1);
+ contacts.add(contact2);
+ contacts.add(contact3);
+
+ return contacts;
+ }
+
+ @GetMapping("/plainWithJavaUtilDate")
+ public List getPlainContactsWithJavaUtilDate() {
+ List contacts = new ArrayList<>();
+
+ PlainContactWithJavaUtilDate contact1 = new PlainContactWithJavaUtilDate("John Doe", "123 Sesame Street", "123-456-789", new Date(), new Date());
+ PlainContactWithJavaUtilDate contact2 = new PlainContactWithJavaUtilDate("John Doe 2", "124 Sesame Street", "123-456-789", new Date(), new Date());
+ PlainContactWithJavaUtilDate contact3 = new PlainContactWithJavaUtilDate("John Doe 3", "125 Sesame Street", "123-456-789", new Date(), new Date());
+
+ contacts.add(contact1);
+ contacts.add(contact2);
+ contacts.add(contact3);
+
+ return contacts;
+ }
+
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactWithJavaUtilDate.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactWithJavaUtilDate.java
new file mode 100644
index 0000000000..5a1c508098
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/ContactWithJavaUtilDate.java
@@ -0,0 +1,69 @@
+package com.baeldung.jsondateformat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.util.Date;
+
+public class ContactWithJavaUtilDate {
+
+ private String name;
+ private String address;
+ private String phone;
+
+ @JsonFormat(pattern="yyyy-MM-dd")
+ private Date birthday;
+
+ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ private Date lastUpdate;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public Date getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(Date birthday) {
+ this.birthday = birthday;
+ }
+
+ public Date getLastUpdate() {
+ return lastUpdate;
+ }
+
+ public void setLastUpdate(Date lastUpdate) {
+ this.lastUpdate = lastUpdate;
+ }
+
+ public ContactWithJavaUtilDate() {
+ }
+
+ public ContactWithJavaUtilDate(String name, String address, String phone, Date birthday, Date lastUpdate) {
+ this.name = name;
+ this.address = address;
+ this.phone = phone;
+ this.birthday = birthday;
+ this.lastUpdate = lastUpdate;
+ }
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/PlainContact.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/PlainContact.java
new file mode 100644
index 0000000000..7e9e53d205
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/PlainContact.java
@@ -0,0 +1,66 @@
+package com.baeldung.jsondateformat;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+public class PlainContact {
+
+ private String name;
+ private String address;
+ private String phone;
+
+ private LocalDate birthday;
+
+ private LocalDateTime lastUpdate;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public LocalDate getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(LocalDate birthday) {
+ this.birthday = birthday;
+ }
+
+ public LocalDateTime getLastUpdate() {
+ return lastUpdate;
+ }
+
+ public void setLastUpdate(LocalDateTime lastUpdate) {
+ this.lastUpdate = lastUpdate;
+ }
+
+ public PlainContact() {
+ }
+
+ public PlainContact(String name, String address, String phone, LocalDate birthday, LocalDateTime lastUpdate) {
+ this.name = name;
+ this.address = address;
+ this.phone = phone;
+ this.birthday = birthday;
+ this.lastUpdate = lastUpdate;
+ }
+}
diff --git a/spring-boot-data/src/main/java/com/baeldung/jsondateformat/PlainContactWithJavaUtilDate.java b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/PlainContactWithJavaUtilDate.java
new file mode 100644
index 0000000000..daefb15543
--- /dev/null
+++ b/spring-boot-data/src/main/java/com/baeldung/jsondateformat/PlainContactWithJavaUtilDate.java
@@ -0,0 +1,69 @@
+package com.baeldung.jsondateformat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.util.Date;
+
+public class PlainContactWithJavaUtilDate {
+
+ private String name;
+ private String address;
+ private String phone;
+
+ @JsonFormat(pattern="yyyy-MM-dd")
+ private Date birthday;
+
+ @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ private Date lastUpdate;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public Date getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(Date birthday) {
+ this.birthday = birthday;
+ }
+
+ public Date getLastUpdate() {
+ return lastUpdate;
+ }
+
+ public void setLastUpdate(Date lastUpdate) {
+ this.lastUpdate = lastUpdate;
+ }
+
+ public PlainContactWithJavaUtilDate() {
+ }
+
+ public PlainContactWithJavaUtilDate(String name, String address, String phone, Date birthday, Date lastUpdate) {
+ this.name = name;
+ this.address = address;
+ this.phone = phone;
+ this.birthday = birthday;
+ this.lastUpdate = lastUpdate;
+ }
+}
diff --git a/spring-boot-data/src/main/resources/application.properties b/spring-boot-data/src/main/resources/application.properties
new file mode 100644
index 0000000000..845b783634
--- /dev/null
+++ b/spring-boot-data/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=Europe/Zagreb
\ No newline at end of file
diff --git a/spring-boot-data/src/test/java/com/baeldung/jsondateformat/ContactAppIntegrationTest.java b/spring-boot-data/src/test/java/com/baeldung/jsondateformat/ContactAppIntegrationTest.java
new file mode 100644
index 0000000000..f76440d1bc
--- /dev/null
+++ b/spring-boot-data/src/test/java/com/baeldung/jsondateformat/ContactAppIntegrationTest.java
@@ -0,0 +1,100 @@
+package com.baeldung.jsondateformat;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = RANDOM_PORT, classes = ContactApp.class)
+@TestPropertySource(properties = {
+ "spring.jackson.date-format=yyyy-MM-dd HH:mm:ss"
+})
+public class ContactAppIntegrationTest {
+
+ private final ObjectMapper mapper = new ObjectMapper();
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Test
+ public void givenJsonFormatAnnotationAndJava8DateType_whenGet_thenReturnExpectedDateFormat() throws IOException, ParseException {
+ ResponseEntity response = restTemplate.getForEntity("http://localhost:" + port + "/contacts", String.class);
+
+ assertEquals(200, response.getStatusCodeValue());
+
+ List