Skip to content

Commit 236fdd9

Browse files
committed
Merge pull request #1193 from mkokho/fail_on_null_creator_properties
Fail on null creator properties when deserializing
2 parents c28e2da + b79e4e3 commit 236fdd9

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,20 @@ public enum DeserializationFeature implements ConfigFeature
230230
* @since 2.6
231231
*/
232232
FAIL_ON_MISSING_CREATOR_PROPERTIES(false),
233-
233+
234+
/**
235+
* Feature that determines what happens if one or more Creator properties (properties
236+
* bound to parameters of Creator method (constructor or static factory method))
237+
* are bound to null values - either from the JSON or as a default value. This
238+
* is useful if you want to avoid nulls in your codebase, and particularly useful
239+
* if you are using Java or Scala optionals for non-mandatory fields.
240+
* Feature is disabled by default, so that no exception is thrown for missing creator
241+
* property values, unless they are explicitly marked as `required`.
242+
*
243+
* @since 2.8
244+
*/
245+
FAIL_ON_NULL_CREATOR_PROPERTIES(false),
246+
234247
/**
235248
* Feature that determines whether Jackson code should catch
236249
* and wrap {@link Exception}s (but never {@link Error}s!)

src/main/java/com/fasterxml/jackson/databind/deser/impl/PropertyValueBuffer.java

+10
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ protected Object[] getParameters(SettableBeanProperty[] props)
125125
}
126126
}
127127
}
128+
129+
if (_context.isEnabled(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES)) {
130+
for (int ix = 0; ix < props.length; ++ix) {
131+
if (_creatorParameters[ix] == null) {
132+
throw _context.mappingException("Null value for creator property '%s'; DeserializationFeature.FAIL_ON_NULL_FOR_CREATOR_PARAMETERS enabled",
133+
props[ix].getName(), props[ix].getCreatorIndex());
134+
}
135+
}
136+
}
137+
128138
return _creatorParameters;
129139
}
130140

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.fasterxml.jackson.databind.creators;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.fasterxml.jackson.databind.*;
6+
7+
/**
8+
* Tests to ensure that deserialization fails when a bean property has a null value
9+
* Relates to <a href="https://github.com/FasterXML/jackson-databind/issues/988">issue #988</a>
10+
*/
11+
public class FailOnNullCreatorTest extends BaseMapTest
12+
{
13+
static class Person {
14+
String name;
15+
Integer age;
16+
17+
@JsonCreator
18+
public Person(@JsonProperty(value="name") String name,
19+
@JsonProperty(value="age") int age)
20+
{
21+
this.name = name;
22+
this.age = age;
23+
}
24+
}
25+
26+
private final ObjectReader POINT_READER = objectMapper().readerFor(Person.class);
27+
28+
public void testRequiredNonNullParam() throws Exception
29+
{
30+
Person p;
31+
// First: fine if feature is not enabled
32+
p = POINT_READER.readValue(aposToQuotes("{}"));
33+
assertEquals(null, p.name);
34+
assertEquals(Integer.valueOf(0), p.age);
35+
36+
// Second: fine if feature is enabled but default value is not null
37+
ObjectReader r = POINT_READER.with(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES);
38+
p = POINT_READER.readValue(aposToQuotes("{'name':'John', 'age': null}"));
39+
assertEquals("John", p.name);
40+
assertEquals(Integer.valueOf(0), p.age);
41+
42+
// Third: throws exception if property is missing
43+
try {
44+
r.readValue(aposToQuotes("{}"));
45+
fail("Should not pass third test");
46+
} catch (JsonMappingException e) {
47+
verifyException(e, "Null value for creator property 'name'");
48+
}
49+
50+
// Fourth: throws exception if property is set to null explicitly
51+
try {
52+
r.readValue(aposToQuotes("{'age': 5, 'name': null}"));
53+
fail("Should not pass fourth test");
54+
} catch (JsonMappingException e) {
55+
verifyException(e, "Null value for creator property 'name'");
56+
}
57+
}
58+
59+
60+
}

0 commit comments

Comments
 (0)