Skip to content

Commit ba7417d

Browse files
authored
Merge pull request FasterXML#38 from Qnzvna/2.9
handling DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES -> 2.9
2 parents 126bfbb + 8b4f1e9 commit ba7417d

File tree

2 files changed

+100
-4
lines changed

2 files changed

+100
-4
lines changed

afterburner/src/main/java/com/fasterxml/jackson/module/afterburner/deser/OptimizedSettableBeanProperty.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,13 @@ protected final boolean _deserializeBoolean(JsonParser p, DeserializationContext
178178
JsonToken t = p.getCurrentToken();
179179
if (t == JsonToken.VALUE_TRUE) return true;
180180
if (t == JsonToken.VALUE_FALSE) return false;
181-
if (t == JsonToken.VALUE_NULL) return false;
181+
if (t == JsonToken.VALUE_NULL) {
182+
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
183+
_failNullToPrimitiveCoercion(ctxt, "boolean");
184+
} else {
185+
return false;
186+
}
187+
}
182188

183189
if (t == JsonToken.VALUE_NUMBER_INT) {
184190
// 11-Jan-2012, tatus: May be outside of int...
@@ -264,7 +270,11 @@ protected final int _deserializeInt(JsonParser p, DeserializationContext ctxt)
264270
return p.getValueAsInt();
265271
}
266272
if (t == JsonToken.VALUE_NULL) {
267-
return 0;
273+
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
274+
_failNullToPrimitiveCoercion(ctxt, "int");
275+
} else {
276+
return 0;
277+
}
268278
}
269279
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
270280
p.nextToken();
@@ -300,7 +310,11 @@ protected final long _deserializeLong(JsonParser p, DeserializationContext ctxt)
300310
} catch (IllegalArgumentException iae) { }
301311
throw ctxt.weirdStringException(text, Long.TYPE, "not a valid long value");
302312
case JsonTokenId.ID_NULL:
303-
return 0L;
313+
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
314+
_failNullToPrimitiveCoercion(ctxt, "long");
315+
} else {
316+
return 0L;
317+
}
304318
case JsonTokenId.ID_START_ARRAY:
305319
if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
306320
p.nextToken();
@@ -368,7 +382,14 @@ protected final boolean _deserializeBooleanFromOther(JsonParser p, Deserializati
368382
}
369383

370384
// // More helper methods from StdDeserializer
371-
385+
386+
protected void _failNullToPrimitiveCoercion(DeserializationContext ctxt, String type) throws JsonMappingException
387+
{
388+
ctxt.reportInputMismatch(getType(),
389+
"Cannot map `null` into type %s (set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)",
390+
type);
391+
}
392+
372393
protected void _failDoubleToIntCoercion(JsonParser p, DeserializationContext ctxt,
373394
String type) throws IOException
374395
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.fasterxml.jackson.module.afterburner.deser;
2+
3+
import com.fasterxml.jackson.databind.DeserializationFeature;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
6+
import com.fasterxml.jackson.module.afterburner.AfterburnerTestBase;
7+
8+
public class TestFailOnPrimitiveFromNullDeserialization extends AfterburnerTestBase
9+
{
10+
static class LongBean
11+
{
12+
public long value;
13+
}
14+
15+
static class IntBean
16+
{
17+
public int value;
18+
}
19+
20+
static class BooleanBean
21+
{
22+
public boolean value;
23+
}
24+
25+
static class DoubleBean
26+
{
27+
public double value;
28+
}
29+
30+
private final static String BEAN_WITH_NULL_VALUE = "{\"value\": null}";
31+
32+
private final ObjectMapper MAPPER = newObjectMapper();
33+
private final ObjectMapper FAIL_ON_NULL_MAPPER = newObjectMapper()
34+
.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
35+
36+
public void testPassPrimitiveFromNull() throws Exception
37+
{
38+
LongBean longBean = MAPPER.readValue(BEAN_WITH_NULL_VALUE, LongBean.class);
39+
IntBean intBean = MAPPER.readValue(BEAN_WITH_NULL_VALUE, IntBean.class);
40+
BooleanBean booleanBean = MAPPER.readValue(BEAN_WITH_NULL_VALUE, BooleanBean.class);
41+
DoubleBean doubleBean = MAPPER.readValue(BEAN_WITH_NULL_VALUE, DoubleBean.class);
42+
assertEquals(longBean.value, 0);
43+
assertEquals(intBean.value, 0);
44+
assertEquals(booleanBean.value, false);
45+
assertEquals(doubleBean.value, 0.0);
46+
}
47+
48+
public void testFailPrimitiveFromNull() throws Exception
49+
{
50+
try {
51+
FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, IntBean.class);
52+
fail();
53+
} catch (MismatchedInputException e) {
54+
verifyException(e, "Cannot map `null` into type int");
55+
}
56+
try {
57+
FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, LongBean.class);
58+
fail();
59+
} catch (MismatchedInputException e) {
60+
verifyException(e, "Cannot map `null` into type long");
61+
}
62+
try {
63+
FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, BooleanBean.class);
64+
fail();
65+
} catch (MismatchedInputException e) {
66+
verifyException(e, "Cannot map `null` into type boolean");
67+
}
68+
try {
69+
FAIL_ON_NULL_MAPPER.readValue(BEAN_WITH_NULL_VALUE, DoubleBean.class);
70+
fail();
71+
} catch (MismatchedInputException e) {
72+
verifyException(e, "Cannot map `null` into type double");
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)