diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java index 3bcb7694..849da541 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java @@ -43,7 +43,7 @@ private LocalDateDeserializer() { this(DateTimeFormatter.ISO_LOCAL_DATE); } - protected LocalDateDeserializer(DateTimeFormatter dtf) { + public LocalDateDeserializer(DateTimeFormatter dtf) { super(LocalDate.class, dtf); } diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateTimeDeserializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateTimeDeserializer.java index b629c415..dbfc1490 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateTimeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateTimeDeserializer.java @@ -42,13 +42,13 @@ private LocalDateTimeDeserializer() { this(DateTimeFormatter.ISO_LOCAL_DATE_TIME); } - protected LocalDateTimeDeserializer(DateTimeFormatter dtf) { - super(LocalDateTime.class, dtf); + public LocalDateTimeDeserializer(DateTimeFormatter formatter) { + super(LocalDateTime.class, formatter); } @Override - protected JsonDeserializer withDateFormat(DateTimeFormatter dtf) { - return new LocalDateTimeDeserializer(dtf); + protected JsonDeserializer withDateFormat(DateTimeFormatter formatter) { + return new LocalDateTimeDeserializer(formatter); } @Override diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserializer.java index c79a6636..e690205c 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalTimeDeserializer.java @@ -42,13 +42,13 @@ private LocalTimeDeserializer() { this(DateTimeFormatter.ISO_LOCAL_TIME); } - protected LocalTimeDeserializer(DateTimeFormatter dtf) { - super(LocalTime.class, dtf); + public LocalTimeDeserializer(DateTimeFormatter formatter) { + super(LocalTime.class, formatter); } @Override - protected JsonDeserializer withDateFormat(DateTimeFormatter dtf) { - return new LocalTimeDeserializer(dtf); + protected JsonDeserializer withDateFormat(DateTimeFormatter formatter) { + return new LocalTimeDeserializer(formatter); } @Override diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearDeserializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearDeserializer.java index e4228bd2..383e9c88 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearDeserializer.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.time.Year; +import java.time.format.DateTimeFormatter; /** * Deserializer for Java 8 temporal {@link Year}s. @@ -31,7 +32,7 @@ public class YearDeserializer extends JSR310DeserializerBase { private static final long serialVersionUID = 1L; - + private DateTimeFormatter formatter; public static final YearDeserializer INSTANCE = new YearDeserializer(); private YearDeserializer() @@ -39,9 +40,17 @@ private YearDeserializer() super(Year.class); } + public YearDeserializer(DateTimeFormatter formatter) { + super(Year.class); + this.formatter = formatter; + } + @Override public Year deserialize(JsonParser parser, DeserializationContext context) throws IOException { - return Year.of(parser.getValueAsInt()); + if (formatter == null) { + return Year.of(parser.getValueAsInt()); + } + return Year.parse(parser.getValueAsString(), formatter); } } diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearMonthDeserializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearMonthDeserializer.java index bb6aa8fa..fdec9cb9 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearMonthDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/YearMonthDeserializer.java @@ -45,9 +45,9 @@ private YearMonthDeserializer() this(DateTimeFormatter.ofPattern("uuuu-MM")); } - protected YearMonthDeserializer(DateTimeFormatter dtf) + public YearMonthDeserializer(DateTimeFormatter formatter) { - super(YearMonth.class, dtf); + super(YearMonth.class, formatter); } @Override diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateSerializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateSerializer.java index 2a1fb77d..2de5aa08 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateSerializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateSerializer.java @@ -44,6 +44,10 @@ protected LocalDateSerializer(LocalDateSerializer base, super(base, useTimestamp, dtf); } + public LocalDateSerializer(DateTimeFormatter formatter) { + super(LocalDate.class, formatter); + } + @Override protected LocalDateSerializer withFormat(Boolean useTimestamp, DateTimeFormatter dtf) { return new LocalDateSerializer(this, useTimestamp, dtf); diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateTimeSerializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateTimeSerializer.java index 9c72b78c..2159eaff 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateTimeSerializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalDateTimeSerializer.java @@ -38,17 +38,20 @@ public class LocalDateTimeSerializer extends JSR310FormattedSerializerBase withFormat(Boolean useTimestamp, DateTimeFormatter dtf) { - return new LocalDateTimeSerializer(this, useTimestamp, dtf); + protected JSR310FormattedSerializerBase withFormat(Boolean useTimestamp, DateTimeFormatter formatter) { + return new LocalDateTimeSerializer(this, useTimestamp, formatter); } @Override diff --git a/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalTimeSerializer.java b/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalTimeSerializer.java index d7aa6106..dd2661e1 100644 --- a/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalTimeSerializer.java +++ b/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/LocalTimeSerializer.java @@ -38,12 +38,15 @@ public class LocalTimeSerializer extends JSR310FormattedSerializerBase public static final YearSerializer INSTANCE = new YearSerializer(); protected YearSerializer() { - super(Year.class); + this(null); } - protected YearSerializer(YearSerializer base, - Boolean useTimestamp, DateTimeFormatter dtf) { - super(base, useTimestamp, dtf); + public YearSerializer(DateTimeFormatter formatter) { + super(Year.class, formatter); + } + + protected YearSerializer(YearSerializer base, Boolean useTimestamp, DateTimeFormatter formatter) { + super(base, useTimestamp, formatter); } @Override - protected YearSerializer withFormat(Boolean useTimestamp, DateTimeFormatter dtf) { - return new YearSerializer(this, useTimestamp, dtf); + protected YearSerializer withFormat(Boolean useTimestamp, DateTimeFormatter formatter) { + return new YearSerializer(this, useTimestamp, formatter); } @Override diff --git a/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalDateSerializationWithCustomFormatter.java b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalDateSerializationWithCustomFormatter.java new file mode 100644 index 00000000..4040e724 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalDateSerializationWithCustomFormatter.java @@ -0,0 +1,62 @@ +package com.fasterxml.jackson.datatype.jsr310; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class TestLocalDateSerializationWithCustomFormatter { + private final DateTimeFormatter formatter; + + public TestLocalDateSerializationWithCustomFormatter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Test + public void testSerialization() throws Exception { + LocalDate date = LocalDate.now(); + assertThat(serializeWith(date, formatter), containsString(date.format(formatter))); + } + + private String serializeWith(LocalDate date, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addSerializer(new LocalDateSerializer(formatter))); + return mapper.writeValueAsString(date); + } + + @Test + public void testDeserialization() throws Exception { + LocalDate date = LocalDate.now(); + assertThat(deserializeWith(date.format(formatter), formatter), equalTo(date)); + } + + private LocalDate deserializeWith(String json, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addDeserializer(LocalDate.class, new LocalDateDeserializer(formatter))); + return mapper.readValue("\"" + json + "\"", LocalDate.class); + } + + @Parameters + public static Collection customFormatters() { + Collection formatters = new ArrayList<>(); + formatters.add(new Object[]{DateTimeFormatter.BASIC_ISO_DATE}); + formatters.add(new Object[]{DateTimeFormatter.ISO_DATE}); + formatters.add(new Object[]{DateTimeFormatter.ISO_LOCAL_DATE}); + formatters.add(new Object[]{DateTimeFormatter.ISO_ORDINAL_DATE}); + formatters.add(new Object[]{DateTimeFormatter.ISO_WEEK_DATE}); + formatters.add(new Object[]{DateTimeFormatter.ofPattern("MM/dd/yyyy")}); + return formatters; + } +} diff --git a/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalDateTimeSerializationWithCustomFormatter.java b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalDateTimeSerializationWithCustomFormatter.java new file mode 100644 index 00000000..ad1d1e5f --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalDateTimeSerializationWithCustomFormatter.java @@ -0,0 +1,62 @@ +package com.fasterxml.jackson.datatype.jsr310; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.ArrayList; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class TestLocalDateTimeSerializationWithCustomFormatter { + private final DateTimeFormatter formatter; + + public TestLocalDateTimeSerializationWithCustomFormatter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Test + public void testSerialization() throws Exception { + LocalDateTime dateTime = LocalDateTime.now(); + assertThat(serializeWith(dateTime, formatter), containsString(dateTime.format(formatter))); + } + + private String serializeWith(LocalDateTime dateTime, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addSerializer(new LocalDateTimeSerializer(formatter))); + return mapper.writeValueAsString(dateTime); + } + + @Test + public void testDeserialization() throws Exception { + LocalDateTime dateTime = LocalDateTime.now(); + assertThat(deserializeWith(dateTime.format(formatter), formatter), equalTo(dateTime)); + } + + private LocalDateTime deserializeWith(String json, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter))); + return mapper.readValue("\"" + json + "\"", LocalDateTime.class); + } + + @Parameters + public static Collection customFormatters() { + Collection formatters = new ArrayList<>(); + formatters.add(new Object[]{DateTimeFormatter.ISO_DATE_TIME}); + formatters.add(new Object[]{DateTimeFormatter.ISO_LOCAL_DATE_TIME}); + return formatters; + } +} diff --git a/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalTimeSerializationWithCustomFormatter.java b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalTimeSerializationWithCustomFormatter.java new file mode 100644 index 00000000..a8edf91b --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestLocalTimeSerializationWithCustomFormatter.java @@ -0,0 +1,59 @@ +package com.fasterxml.jackson.datatype.jsr310; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.util.ArrayList; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class TestLocalTimeSerializationWithCustomFormatter { + private final DateTimeFormatter formatter; + + public TestLocalTimeSerializationWithCustomFormatter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Test + public void testSerialization() throws Exception { + LocalTime dateTime = LocalTime.now(); + assertThat(serializeWith(dateTime, formatter), containsString(dateTime.format(formatter))); + } + + private String serializeWith(LocalTime dateTime, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addSerializer(new LocalTimeSerializer(formatter))); + return mapper.writeValueAsString(dateTime); + } + + @Test + public void testDeserialization() throws Exception { + LocalTime dateTime = LocalTime.now(); + assertThat(deserializeWith(dateTime.format(formatter), formatter), equalTo(dateTime)); + } + + private LocalTime deserializeWith(String json, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addDeserializer(LocalTime.class, new LocalTimeDeserializer(formatter))); + return mapper.readValue("\"" + json + "\"", LocalTime.class); + } + + @Parameters + public static Collection customFormatters() { + Collection formatters = new ArrayList<>(); + formatters.add(new Object[]{DateTimeFormatter.ISO_LOCAL_TIME}); + formatters.add(new Object[]{DateTimeFormatter.ISO_TIME}); + return formatters; + } +} diff --git a/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestYearMonthSerializationWithCustomFormatter.java b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestYearMonthSerializationWithCustomFormatter.java new file mode 100644 index 00000000..e493e03a --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestYearMonthSerializationWithCustomFormatter.java @@ -0,0 +1,58 @@ +package com.fasterxml.jackson.datatype.jsr310; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.YearMonthDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.YearMonthSerializer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class TestYearMonthSerializationWithCustomFormatter { + private final DateTimeFormatter formatter; + + public TestYearMonthSerializationWithCustomFormatter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Test + public void testSerialization() throws Exception { + YearMonth dateTime = YearMonth.now(); + assertThat(serializeWith(dateTime, formatter), containsString(dateTime.format(formatter))); + } + + private String serializeWith(YearMonth dateTime, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addSerializer(new YearMonthSerializer(formatter))); + return mapper.writeValueAsString(dateTime); + } + + @Test + public void testDeserialization() throws Exception { + YearMonth dateTime = YearMonth.now(); + assertThat(deserializeWith(dateTime.format(formatter), formatter), equalTo(dateTime)); + } + + private YearMonth deserializeWith(String json, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addDeserializer(YearMonth.class, new YearMonthDeserializer(formatter))); + return mapper.readValue("\"" + json + "\"", YearMonth.class); + } + + @Parameters + public static Collection customFormatters() { + Collection formatters = new ArrayList<>(); + formatters.add(new Object[]{DateTimeFormatter.ofPattern("uuuu-MM")}); + formatters.add(new Object[]{DateTimeFormatter.ofPattern("uu-M")}); + return formatters; + } +} diff --git a/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestYearSerializationWithCustomFormatter.java b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestYearSerializationWithCustomFormatter.java new file mode 100644 index 00000000..deaeca82 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/datatype/jsr310/TestYearSerializationWithCustomFormatter.java @@ -0,0 +1,59 @@ +package com.fasterxml.jackson.datatype.jsr310; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.deser.YearDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.YearSerializer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.time.Year; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class TestYearSerializationWithCustomFormatter { + private final DateTimeFormatter formatter; + + public TestYearSerializationWithCustomFormatter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + @Test + public void testSerialization() throws Exception { + Year year = Year.now(); + String expected = "\"" + year.format(formatter) + "\""; + assertThat(serializeWith(year, formatter), equalTo(expected)); + } + + private String serializeWith(Year dateTime, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addSerializer(new YearSerializer(formatter))); + return mapper.writeValueAsString(dateTime); + } + + @Test + public void testDeserialization() throws Exception { + Year dateTime = Year.now(); + assertThat(deserializeWith(dateTime.format(formatter), formatter), equalTo(dateTime)); + } + + private Year deserializeWith(String json, DateTimeFormatter formatter) throws Exception { + ObjectMapper mapper = new ObjectMapper().registerModule(new SimpleModule().addDeserializer(Year.class, new YearDeserializer(formatter))); + return mapper.readValue("\"" + json + "\"", Year.class); + } + + @Parameters + public static Collection customFormatters() { + Collection formatters = new ArrayList<>(); + formatters.add(new Object[]{DateTimeFormatter.ofPattern("yyyy")}); + formatters.add(new Object[]{DateTimeFormatter.ofPattern("yy")}); + return formatters; + } +}