diff --git a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java index 825290fa..fbec5c47 100644 --- a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java +++ b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java @@ -27,6 +27,8 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.cfg.CoercionAction; +import com.fasterxml.jackson.databind.cfg.CoercionInputShape; /** * Deserializer for Java 8 temporal {@link LocalDate}s. @@ -127,6 +129,11 @@ public LocalDate deserialize(JsonParser parser, DeserializationContext context) } // 06-Jan-2018, tatu: Is this actually safe? Do users expect such coercion? if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) { + CoercionAction act = context.findCoercionAction(logicalType(), _valueClass, + CoercionInputShape.Integer); + _checkCoercionFail(context, act, handledType(), parser.getLongValue(), + "Integer value (" + parser.getLongValue() + ")"); + // issue 58 - also check for NUMBER_INT, which needs to be specified when serializing. if (_shape == JsonFormat.Shape.NUMBER_INT || isLenient()) { return LocalDate.ofEpochDay(parser.getLongValue()); diff --git a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java index d6a603fa..e3fe9e92 100644 --- a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java +++ b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java @@ -1,10 +1,5 @@ package com.fasterxml.jackson.datatype.jsr310.deser; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - import java.io.IOException; import java.time.Instant; import java.time.LocalDate; @@ -16,6 +11,8 @@ import java.util.Map; import com.fasterxml.jackson.annotation.OptBoolean; +import com.fasterxml.jackson.databind.cfg.CoercionAction; +import com.fasterxml.jackson.databind.cfg.CoercionInputShape; import com.fasterxml.jackson.databind.exc.InvalidFormatException; import org.junit.Test; @@ -33,6 +30,11 @@ import com.fasterxml.jackson.datatype.jsr310.MockObjectConfiguration; import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.*; +import static org.junit.Assert.assertThrows; + public class LocalDateDeserTest extends ModuleTestBase { private final ObjectMapper MAPPER = newMapper(); @@ -476,7 +478,7 @@ public void testLenientDeserializeFromNumberInt() throws Exception { mapper.configOverride(LocalDate.class) .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.NUMBER_INT)); - assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 04), + assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 4), mapper.readValue("123", LocalDate.class)); } @@ -490,7 +492,7 @@ public void testStrictDeserializeFromNumberInt() throws Exception ShapeWrapper w = mapper.readValue("{\"date\":123}", ShapeWrapper.class); LocalDate localDate = w.date; - assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 04), + assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 4), localDate); } @@ -504,6 +506,38 @@ public void testStrictDeserializeFromString() throws Exception mapper.readValue("{\"value\":123}", Wrapper.class); } + /********************************************************************** + * + * coercion config test + * + /********************************************************************** + */ + @Test + public void testDeserializeFromIntegerWithCoercionActionFail() { + ObjectMapper mapper = newMapper(); + mapper.coercionConfigFor(LocalDate.class) + .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail); + + MismatchedInputException exception = assertThrows(MismatchedInputException.class, + () -> mapper.readValue("123", LocalDate.class)); + + assertThat(exception.getMessage(), + containsString("Cannot coerce Integer value (123) to `java.time.LocalDate`")); + } + + @Test + public void testDeserializeFromEmptyStringWithCoercionActionFail() { + ObjectMapper mapper = newMapper(); + mapper.coercionConfigFor(LocalDate.class) + .setCoercion(CoercionInputShape.EmptyString, CoercionAction.Fail); + + MismatchedInputException exception = assertThrows(MismatchedInputException.class, + () -> mapper.readValue(a2q("{'value':''}"), Wrapper.class)); + + assertThat(exception.getMessage(), + containsString("Cannot coerce empty String (\"\") to `java.time.LocalDate`")); + } + /* /********************************************************************** /* Helper methods