diff --git a/jackson/pom.xml b/jackson/pom.xml
index 569c7f5028..247bab72b0 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -45,6 +45,12 @@
${jackson.version}
+
+ joda-time
+ joda-time
+ 2.6
+
+
com.google.code.gson
gson
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/CustomDateDeserializer.java b/jackson/src/test/java/org/baeldung/jackson/date/CustomDateDeserializer.java
new file mode 100644
index 0000000000..bbd039f6ae
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/CustomDateDeserializer.java
@@ -0,0 +1,27 @@
+package org.baeldung.jackson.date;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+
+public class CustomDateDeserializer extends JsonDeserializer {
+
+ private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ @Override
+ public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
+ final String date = jsonparser.getText();
+ try {
+ return formatter.parse(date);
+ } catch (final ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/CustomDateSerializer.java b/jackson/src/test/java/org/baeldung/jackson/date/CustomDateSerializer.java
new file mode 100644
index 0000000000..fc7cbb2db1
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/CustomDateSerializer.java
@@ -0,0 +1,20 @@
+package org.baeldung.jackson.date;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+public class CustomDateSerializer extends JsonSerializer {
+
+ private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ @Override
+ public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.format(value));
+ }
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/CustomDateTimeSerializer.java b/jackson/src/test/java/org/baeldung/jackson/date/CustomDateTimeSerializer.java
new file mode 100644
index 0000000000..9f2a290bc4
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/CustomDateTimeSerializer.java
@@ -0,0 +1,22 @@
+package org.baeldung.jackson.date;
+
+import java.io.IOException;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+public class CustomDateTimeSerializer extends JsonSerializer {
+
+ private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
+
+ @Override
+ public void serialize(final DateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.print(value));
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/CustomLocalDateTimeSerializer.java b/jackson/src/test/java/org/baeldung/jackson/date/CustomLocalDateTimeSerializer.java
new file mode 100644
index 0000000000..b1e6a8ba86
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/CustomLocalDateTimeSerializer.java
@@ -0,0 +1,20 @@
+package org.baeldung.jackson.date;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+public class CustomLocalDateTimeSerializer extends JsonSerializer {
+
+ private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
+ @Override
+ public void serialize(final LocalDateTime value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.format(value));
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/Event.java b/jackson/src/test/java/org/baeldung/jackson/date/Event.java
new file mode 100644
index 0000000000..783eee6af8
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/Event.java
@@ -0,0 +1,25 @@
+package org.baeldung.jackson.date;
+
+import java.util.Date;
+
+public class Event {
+ public String name;
+ public Date eventDate;
+
+ public Event() {
+ super();
+ }
+
+ public Event(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/EventWithFormat.java b/jackson/src/test/java/org/baeldung/jackson/date/EventWithFormat.java
new file mode 100644
index 0000000000..4b2053eb4b
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/EventWithFormat.java
@@ -0,0 +1,29 @@
+package org.baeldung.jackson.date;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+public class EventWithFormat {
+ public String name;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
+ public Date eventDate;
+
+ public EventWithFormat() {
+ super();
+ }
+
+ public EventWithFormat(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/EventWithJodaTime.java b/jackson/src/test/java/org/baeldung/jackson/date/EventWithJodaTime.java
new file mode 100644
index 0000000000..0c72030650
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/EventWithJodaTime.java
@@ -0,0 +1,29 @@
+package org.baeldung.jackson.date;
+
+import org.joda.time.DateTime;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithJodaTime {
+ public String name;
+
+ @JsonSerialize(using = CustomDateTimeSerializer.class)
+ public DateTime eventDate;
+
+ public EventWithJodaTime() {
+ super();
+ }
+
+ public EventWithJodaTime(final String name, final DateTime eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public DateTime getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/EventWithLocalDateTime.java b/jackson/src/test/java/org/baeldung/jackson/date/EventWithLocalDateTime.java
new file mode 100644
index 0000000000..6c48cf3f0e
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/EventWithLocalDateTime.java
@@ -0,0 +1,29 @@
+package org.baeldung.jackson.date;
+
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithLocalDateTime {
+ public String name;
+
+ @JsonSerialize(using = CustomLocalDateTimeSerializer.class)
+ public LocalDateTime eventDate;
+
+ public EventWithLocalDateTime() {
+ super();
+ }
+
+ public EventWithLocalDateTime(final String name, final LocalDateTime eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public LocalDateTime getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/date/EventWithSerializer.java b/jackson/src/test/java/org/baeldung/jackson/date/EventWithSerializer.java
new file mode 100644
index 0000000000..9cdd6a0fab
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/date/EventWithSerializer.java
@@ -0,0 +1,31 @@
+package org.baeldung.jackson.date;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithSerializer {
+ public String name;
+
+ @JsonDeserialize(using = CustomDateDeserializer.class)
+ @JsonSerialize(using = CustomDateSerializer.class)
+ public Date eventDate;
+
+ public EventWithSerializer() {
+ super();
+ }
+
+ public EventWithSerializer(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson/src/test/java/org/baeldung/jackson/test/JacksonDateTest.java b/jackson/src/test/java/org/baeldung/jackson/test/JacksonDateTest.java
new file mode 100644
index 0000000000..42980baa18
--- /dev/null
+++ b/jackson/src/test/java/org/baeldung/jackson/test/JacksonDateTest.java
@@ -0,0 +1,143 @@
+package org.baeldung.jackson.test;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.baeldung.jackson.date.Event;
+import org.baeldung.jackson.date.EventWithFormat;
+import org.baeldung.jackson.date.EventWithJodaTime;
+import org.baeldung.jackson.date.EventWithLocalDateTime;
+import org.baeldung.jackson.date.EventWithSerializer;
+import org.joda.time.DateTime;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+public class JacksonDateTest {
+
+ @Test
+ public void whenSerializeDateWithJackson_thenSerializedToNumber() throws JsonProcessingException, ParseException {
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ final String toParse = "01-01-1970 01:00";
+ final Date date = df.parse(toParse);
+ final Event event = new Event("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString("3600000"));
+ }
+
+ @Test
+ public void whenSerializeDateToISO8601_thenSerializedToText() throws JsonProcessingException, ParseException {
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ final String toParse = "01-01-1970 02:30";
+ final Date date = df.parse(toParse);
+ final Event event = new Event("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString("1970-01-01T02:30:00.000+0000"));
+ }
+
+ @Test
+ public void whenSetObjectMapperDateFormat_thenCorrect() throws JsonProcessingException, ParseException {
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");
+
+ final String toParse = "20-12-2014 02:30";
+ final Date date = df.parse(toParse);
+ final Event event = new Event("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.setDateFormat(df);
+
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString(toParse));
+ }
+
+ @Test
+ public void whenUseJsonFormatAnnotationToFormatDate_thenCorrect() throws JsonProcessingException, ParseException {
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ final String toParse = "20-12-2014 02:30:00";
+ final Date date = df.parse(toParse);
+ final EventWithFormat event = new EventWithFormat("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString(toParse));
+ }
+
+ @Test
+ public void whenUseCustomDateSerializer_thenCorrect() throws JsonProcessingException, ParseException {
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ final String toParse = "20-12-2014 02:30:00";
+ final Date date = df.parse(toParse);
+ final EventWithSerializer event = new EventWithSerializer("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString(toParse));
+ }
+
+ @Test
+ public void whenSerializeJodaTimeWithJackson_thenCorrect() throws JsonProcessingException {
+ final DateTime date = new DateTime(2014, 12, 20, 2, 30);
+ final EventWithJodaTime event = new EventWithJodaTime("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString("2014-12-20 02:30"));
+ }
+
+ @Test
+ public void whenSerializeJava8DateWithCustomSerializer_thenCorrect() throws JsonProcessingException {
+ final LocalDateTime date = LocalDateTime.of(2014, 12, 20, 2, 30);
+ final EventWithLocalDateTime event = new EventWithLocalDateTime("party", date);
+
+ final ObjectMapper mapper = new ObjectMapper();
+ final String result = mapper.writeValueAsString(event);
+ assertThat(result, containsString("2014-12-20 02:30"));
+ }
+
+ @Test
+ public void whenDeserializeDateWithJackson_thenCorrect() throws JsonProcessingException, IOException {
+ final String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}";
+
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.setDateFormat(df);
+
+ final Event event = mapper.reader(Event.class).readValue(json);
+ assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
+ }
+
+ @Test
+ public void whenDeserializeDateUsingCustomDeserializer_thenCorrect() throws JsonProcessingException, IOException {
+ final String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}";
+
+ final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+ final ObjectMapper mapper = new ObjectMapper();
+
+ final EventWithSerializer event = mapper.reader(EventWithSerializer.class).readValue(json);
+ assertEquals("20-12-2014 02:30:00", df.format(event.eventDate));
+ }
+
+}
diff --git a/spring-rest/src/main/java/org/baeldung/config/WebConfig.java b/spring-rest/src/main/java/org/baeldung/config/WebConfig.java
index fe73f719bf..999f890ebb 100644
--- a/spring-rest/src/main/java/org/baeldung/config/WebConfig.java
+++ b/spring-rest/src/main/java/org/baeldung/config/WebConfig.java
@@ -1,10 +1,12 @@
package org.baeldung.config;
+import java.text.SimpleDateFormat;
import java.util.List;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.xstream.XStreamMarshaller;
@@ -25,7 +27,12 @@ public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(final List> messageConverters) {
messageConverters.add(createXmlHttpMessageConverter());
- messageConverters.add(new MappingJackson2HttpMessageConverter());
+ // messageConverters.add(new MappingJackson2HttpMessageConverter());
+
+ final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
+ builder.indentOutput(true).dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm"));
+ messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
+ // messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
super.configureMessageConverters(messageConverters);
}
diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java b/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java
index 3c06dd4129..cfde4b23b1 100644
--- a/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java
+++ b/spring-rest/src/main/java/org/baeldung/web/controller/ItemController.java
@@ -1,5 +1,7 @@
package org.baeldung.web.controller;
+import java.util.Date;
+
import org.baeldung.web.dto.Item;
import org.baeldung.web.dto.ItemManager;
import org.baeldung.web.dto.Views;
@@ -23,4 +25,9 @@ public class ItemController {
public Item getItemInternal(@PathVariable final int id) {
return ItemManager.getById(id);
}
+
+ @RequestMapping("/date")
+ public Date getCurrentDate() {
+ return new Date();
+ }
}
\ No newline at end of file