Skip to content

Commit 57a765f

Browse files
authored
LocalDateDeserializer should take into account defined actions of 'Fail for Numbers' in coerceConfig (#240)
1 parent d9351cb commit 57a765f

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserializer.java

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.fasterxml.jackson.databind.DeserializationContext;
2828
import com.fasterxml.jackson.databind.DeserializationFeature;
2929
import com.fasterxml.jackson.databind.JavaType;
30+
import com.fasterxml.jackson.databind.cfg.CoercionAction;
31+
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
3032

3133
/**
3234
* Deserializer for Java 8 temporal {@link LocalDate}s.
@@ -127,6 +129,11 @@ public LocalDate deserialize(JsonParser parser, DeserializationContext context)
127129
}
128130
// 06-Jan-2018, tatu: Is this actually safe? Do users expect such coercion?
129131
if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
132+
CoercionAction act = context.findCoercionAction(logicalType(), _valueClass,
133+
CoercionInputShape.Integer);
134+
_checkCoercionFail(context, act, handledType(), parser.getLongValue(),
135+
"Integer value (" + parser.getLongValue() + ")");
136+
130137
// issue 58 - also check for NUMBER_INT, which needs to be specified when serializing.
131138
if (_shape == JsonFormat.Shape.NUMBER_INT || isLenient()) {
132139
return LocalDate.ofEpochDay(parser.getLongValue());

datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/LocalDateDeserTest.java

+41-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package com.fasterxml.jackson.datatype.jsr310.deser;
22

3-
import static org.junit.Assert.assertEquals;
4-
import static org.junit.Assert.assertNotNull;
5-
import static org.junit.Assert.assertNull;
6-
import static org.junit.Assert.fail;
7-
83
import java.io.IOException;
94
import java.time.Instant;
105
import java.time.LocalDate;
@@ -16,6 +11,8 @@
1611
import java.util.Map;
1712

1813
import com.fasterxml.jackson.annotation.OptBoolean;
14+
import com.fasterxml.jackson.databind.cfg.CoercionAction;
15+
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
1916
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
2017
import org.junit.Test;
2118

@@ -33,6 +30,11 @@
3330
import com.fasterxml.jackson.datatype.jsr310.MockObjectConfiguration;
3431
import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase;
3532

33+
import static org.hamcrest.CoreMatchers.containsString;
34+
import static org.hamcrest.MatcherAssert.assertThat;
35+
import static org.junit.Assert.*;
36+
import static org.junit.Assert.assertThrows;
37+
3638
public class LocalDateDeserTest extends ModuleTestBase
3739
{
3840
private final ObjectMapper MAPPER = newMapper();
@@ -476,7 +478,7 @@ public void testLenientDeserializeFromNumberInt() throws Exception {
476478
mapper.configOverride(LocalDate.class)
477479
.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.NUMBER_INT));
478480

479-
assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 04),
481+
assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 4),
480482
mapper.readValue("123", LocalDate.class));
481483
}
482484

@@ -490,7 +492,7 @@ public void testStrictDeserializeFromNumberInt() throws Exception
490492
ShapeWrapper w = mapper.readValue("{\"date\":123}", ShapeWrapper.class);
491493
LocalDate localDate = w.date;
492494

493-
assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 04),
495+
assertEquals("The value is not correct.", LocalDate.of(1970, Month.MAY, 4),
494496
localDate);
495497
}
496498

@@ -504,6 +506,38 @@ public void testStrictDeserializeFromString() throws Exception
504506
mapper.readValue("{\"value\":123}", Wrapper.class);
505507
}
506508

509+
/**********************************************************************
510+
*
511+
* coercion config test
512+
*
513+
/**********************************************************************
514+
*/
515+
@Test
516+
public void testDeserializeFromIntegerWithCoercionActionFail() {
517+
ObjectMapper mapper = newMapper();
518+
mapper.coercionConfigFor(LocalDate.class)
519+
.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail);
520+
521+
MismatchedInputException exception = assertThrows(MismatchedInputException.class,
522+
() -> mapper.readValue("123", LocalDate.class));
523+
524+
assertThat(exception.getMessage(),
525+
containsString("Cannot coerce Integer value (123) to `java.time.LocalDate`"));
526+
}
527+
528+
@Test
529+
public void testDeserializeFromEmptyStringWithCoercionActionFail() {
530+
ObjectMapper mapper = newMapper();
531+
mapper.coercionConfigFor(LocalDate.class)
532+
.setCoercion(CoercionInputShape.EmptyString, CoercionAction.Fail);
533+
534+
MismatchedInputException exception = assertThrows(MismatchedInputException.class,
535+
() -> mapper.readValue(a2q("{'value':''}"), Wrapper.class));
536+
537+
assertThat(exception.getMessage(),
538+
containsString("Cannot coerce empty String (\"\") to `java.time.LocalDate`"));
539+
}
540+
507541
/*
508542
/**********************************************************************
509543
/* Helper methods

0 commit comments

Comments
 (0)