From 712745c69566becd410e1574c849788876c19b99 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 31 Jul 2019 21:01:03 -0700 Subject: [PATCH] Fixed #2392 --- release-notes/VERSION-2.x | 2 ++ .../deser/BasicDeserializerFactory.java | 6 ++--- .../deser/BeanDeserializerFactory.java | 18 +++++++++----- .../deser/BeanDeserializerModifier.java | 24 ++++++++++++++++++- .../deser/TestCustomDeserializers.java | 21 ++++++++++++++++ 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 017cc8195c..2f803251fb 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -8,6 +8,8 @@ Project: jackson-databind #2331: `JsonMappingException` through nested getter with generic wildcard return type (reported by sunchezz89@github) +#2392: `BeanDeserializerModifier.modifyDeserializer()` not applied to custom bean deserializers + (reported by andreasbaus@github) #2393: `TreeTraversingParser.getLongValue()` incorrectly checks `canConvertToInt()` (reported by RabbidDog@github) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java index 3893ea3171..cbac1bfeba 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java @@ -1102,7 +1102,7 @@ public JsonDeserializer createArrayDeserializer(DeserializationContext ctxt, } deser = new ObjectArrayDeserializer(type, contentDeser, elemTypeDeser); } - // and then new with 2.2: ability to post-process it too (Issue#120) + // and then new with 2.2: ability to post-process it too (databind#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyArrayDeserializer(config, type, beanDesc, deser); @@ -1112,9 +1112,9 @@ public JsonDeserializer createArrayDeserializer(DeserializationContext ctxt, } /* - /********************************************************** + /********************************************************************** /* JsonDeserializerFactory impl: Collection(-like) deserializers - /********************************************************** + /********************************************************************** */ @Override diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java index 1f02d709f8..0df42e0257 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java @@ -86,6 +86,7 @@ public DeserializerFactory withConfig(DeserializerFactoryConfig config) * deserializer for types other than Collections, Maps, arrays and * enums. */ + @SuppressWarnings("unchecked") @Override public JsonDeserializer createBeanDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) @@ -93,9 +94,15 @@ public JsonDeserializer createBeanDeserializer(DeserializationContext ct { final DeserializationConfig config = ctxt.getConfig(); // We may also have custom overrides: - JsonDeserializer custom = _findCustomBeanDeserializer(type, config, beanDesc); - if (custom != null) { - return custom; + JsonDeserializer deser = _findCustomBeanDeserializer(type, config, beanDesc); + if (deser != null) { + // [databind#2392] + if (_factoryConfig.hasDeserializerModifiers()) { + for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { + deser = mod.modifyDeserializer(ctxt.getConfig(), beanDesc, deser); + } + } + return (JsonDeserializer) deser; } /* One more thing to check: do we have an exception type * (Throwable or its sub-classes)? If so, need slightly @@ -121,10 +128,9 @@ public JsonDeserializer createBeanDeserializer(DeserializationContext ct } } // Otherwise, may want to check handlers for standard types, from superclass: - @SuppressWarnings("unchecked") - JsonDeserializer deser = (JsonDeserializer) findStdDeserializer(ctxt, type, beanDesc); + deser = findStdDeserializer(ctxt, type, beanDesc); if (deser != null) { - return deser; + return (JsonDeserializer)deser; } // Otherwise: could the class be a Bean class? If not, bail out diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerModifier.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerModifier.java index 0daeee22bd..6caa95b4e0 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerModifier.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerModifier.java @@ -81,9 +81,13 @@ public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, * Method called by {@link BeanDeserializerFactory} after constructing default * bean deserializer instance with properties collected and ordered earlier. * Implementations can modify or replace given deserializer and return deserializer - * to use. Note that although initial deserializer being passed is of type + * to use. Note that although initial deserializer being passed is usually of type * {@link BeanDeserializer}, modifiers may return deserializers of other types; * and this is why implementations must check for type before casting. + *

+ * Since 2.10 this is also called for custom deserializers for types not deemed to + * be of any more specific (reference, enum, array, collection(-like), map(-like), + * node type) */ public JsonDeserializer modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer deserializer) { @@ -97,6 +101,9 @@ public JsonDeserializer modifyDeserializer(DeserializationConfig config, */ /** + * Method called by {@link BeanDeserializerFactory} after constructing default + * enum type deserializer instance. + * * @since 2.2 */ public JsonDeserializer modifyEnumDeserializer(DeserializationConfig config, @@ -105,6 +112,9 @@ public JsonDeserializer modifyEnumDeserializer(DeserializationConfig config, } /** + * Method called by {@link BeanDeserializerFactory} after constructing default + * {@link ReferenceType} deserializer instance. + * * @since 2.7 */ public JsonDeserializer modifyReferenceDeserializer(DeserializationConfig config, @@ -135,6 +145,9 @@ public JsonDeserializer modifyArrayDeserializer(DeserializationConfig config, } /** + * Method called by {@link BeanDeserializerFactory} after constructing default + * {@link CollectionType} deserializer instance. + * * @since 2.2 */ public JsonDeserializer modifyCollectionDeserializer(DeserializationConfig config, @@ -143,6 +156,9 @@ public JsonDeserializer modifyCollectionDeserializer(DeserializationConfig co } /** + * Method called by {@link BeanDeserializerFactory} after constructing default + * {@link CollectionLikeType} deserializer instance. + * * @since 2.2 */ public JsonDeserializer modifyCollectionLikeDeserializer(DeserializationConfig config, @@ -151,6 +167,9 @@ public JsonDeserializer modifyCollectionLikeDeserializer(DeserializationConfi } /** + * Method called by {@link BeanDeserializerFactory} after constructing default + * {@link MapType} deserializer instance. + * * @since 2.2 */ public JsonDeserializer modifyMapDeserializer(DeserializationConfig config, @@ -159,6 +178,9 @@ public JsonDeserializer modifyMapDeserializer(DeserializationConfig config, } /** + * Method called by {@link BeanDeserializerFactory} after constructing default + * {@link MapLikeType} deserializer instance. + * * @since 2.2 */ public JsonDeserializer modifyMapLikeDeserializer(DeserializationConfig config, diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/TestCustomDeserializers.java b/src/test/java/com/fasterxml/jackson/databind/deser/TestCustomDeserializers.java index f85d995386..71b61e6976 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/TestCustomDeserializers.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/TestCustomDeserializers.java @@ -456,4 +456,25 @@ public void testDelegatingDeserializer() throws Exception String str = mapper.readValue(quote("foo"), String.class); assertEquals("MY:foo", str); } + + // [databind#2392] + public void testModifyingCustomDeserializer() throws Exception + { + ObjectMapper mapper = jsonMapperBuilder() + .addModule(new SimpleModule() + .setDeserializerModifier(new BeanDeserializerModifier() { + @Override + public JsonDeserializer modifyDeserializer(DeserializationConfig config, + BeanDescription beanDesc, JsonDeserializer deserializer) { + if (deserializer instanceof DummyDeserializer) { + return new DummyDeserializer("FOOBAR", String.class); + } + return deserializer; + } + }) + .addDeserializer(String.class, new DummyDeserializer("dummy", String.class)) + ).build(); + String str = mapper.readValue(quote("foo"), String.class); + assertEquals("FOOBAR", str); + } }