Skip to content

Commit 7664e53

Browse files
authored
Fix #4934 (#4943)
1 parent 5ddf8b3 commit 7664e53

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

release-notes/CREDITS-2.x

+5
Original file line numberDiff line numberDiff line change
@@ -1904,3 +1904,8 @@ Konstantin Maliuga (@badoken)
19041904
Lars Benedetto (@lbenedetto)
19051905
* Contributed #4676: Support other enum naming strategies than camelCase
19061906
(2.19.0)
1907+
1908+
Floris Westerman (@FWest98)
1909+
* Reported #4934: `DeserializationContext.readTreeAsValue()` handles null nodes
1910+
differently from `ObjectMapper.treeToValue()`
1911+
(2.19.0)

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ Project: jackson-databind
4343
#4869: Add `JsonNode.values()` to replace `elements()`
4444
#4896: Coercion shouldn't be necessary for Enums specifying an empty string
4545
(reported by @joaocanaverde-blue)
46+
#4934: `DeserializationContext.readTreeAsValue()` handles null nodes
47+
differently from `ObjectMapper.treeToValue()`
48+
(reported by Floris W)
4649
4750
2.18.3 (not yet released)
4851

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

+17-3
Original file line numberDiff line numberDiff line change
@@ -989,9 +989,9 @@ public <T> T readValue(JsonParser p, JavaType type) throws IOException {
989989
return reportBadDefinition(type,
990990
"Could not find JsonDeserializer for type "+ClassUtil.getTypeDescription(type));
991991
}
992-
return (T) deser.deserialize(p, this);
992+
return (T) _readValue(p, deser);
993993
}
994-
994+
995995
/**
996996
* Convenience method that may be used by composite or container deserializers,
997997
* for reading one-off values for the composite type, taking into account
@@ -1023,7 +1023,7 @@ public <T> T readPropertyValue(JsonParser p, BeanProperty prop, JavaType type) t
10231023
"Could not find JsonDeserializer for type %s (via property %s)",
10241024
ClassUtil.getTypeDescription(type), ClassUtil.nameOf(prop)));
10251025
}
1026-
return (T) deser.deserialize(p, this);
1026+
return (T) _readValue(p, deser);
10271027
}
10281028

10291029
/**
@@ -1116,6 +1116,20 @@ private TreeTraversingParser _treeAsTokens(JsonNode n) throws IOException
11161116
return p;
11171117
}
11181118

1119+
/**
1120+
* Helper method that should handle special cases for deserialization; most
1121+
* notably handling {@code null} (and possibly absent values).
1122+
*
1123+
* @since 2.19
1124+
*/
1125+
private Object _readValue(JsonParser p, JsonDeserializer<Object> deser) throws IOException
1126+
{
1127+
if (p.hasToken(JsonToken.VALUE_NULL)) {
1128+
return deser.getNullValue(this);
1129+
}
1130+
return deser.deserialize(p, this);
1131+
}
1132+
11191133
/*
11201134
/**********************************************************
11211135
/* Methods for problem handling

src/test/java/com/fasterxml/jackson/databind/DeserializationContextTest.java

+9-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111

1212
public class DeserializationContextTest extends DatabindTestUtil
1313
{
14-
private final ObjectMapper MAPPER = newJsonMapper();
14+
// Not testing "no nulls for primitives", so
15+
private final ObjectMapper MAPPER = jsonMapperBuilder()
16+
.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
17+
.build();
1518

1619
static class Bean4934 {
1720
public String value;
@@ -27,10 +30,9 @@ public void testTreeAsValueFromNulls() throws Exception
2730

2831
assertNull(ctxt.readTreeAsValue(nodeF.nullNode(), Boolean.class));
2932
assertEquals(Boolean.FALSE, ctxt.readTreeAsValue(nodeF.nullNode(), Boolean.TYPE));
33+
assertNull(ctxt.readTreeAsValue(nodeF.nullNode(), String.class));
3034

31-
// Only fixed in 2.19:
32-
//assertNull(ctxt.readTreeAsValue(nodeF.nullNode(), Bean4934.class));
33-
35+
assertNull(ctxt.readTreeAsValue(nodeF.nullNode(), Bean4934.class));
3436
}
3537
}
3638

@@ -42,12 +44,12 @@ public void testTreeAsValueFromMissing() throws Exception
4244
try (JsonParser p = MAPPER.createParser("abc")) {
4345
DeserializationContext ctxt = MAPPER.readerFor(String.class).createDeserializationContext(p);
4446

45-
assertNull(ctxt.readTreeAsValue(nodeF.missingNode(), Boolean.class));
4647
// Absent becomes `null` for now as well
48+
assertNull(ctxt.readTreeAsValue(nodeF.missingNode(), Boolean.class));
4749
assertNull(ctxt.readTreeAsValue(nodeF.missingNode(), Boolean.TYPE));
50+
assertNull(ctxt.readTreeAsValue(nodeF.missingNode(), String.class));
4851

49-
// Only fixed in 2.19:
50-
//assertNull(ctxt.readTreeAsValue(nodeF.missingNode(), Bean4934.class));
52+
assertNull(ctxt.readTreeAsValue(nodeF.missingNode(), Bean4934.class));
5153
}
5254
}
5355
}

0 commit comments

Comments
 (0)