From 68f514bdd80640522edc535ba86e3e81ff9debd1 Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 18 Oct 2023 22:20:47 -0700 Subject: [PATCH] Refine initialization of the TypeResolver in GenericJackson2JsonRedisSerializer. Closes #2750 --- .../GenericJackson2JsonRedisSerializer.java | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java index 05841a214..550dfc31a 100644 --- a/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java @@ -23,7 +23,6 @@ import java.util.function.Supplier; import org.springframework.cache.support.NullValue; import org.springframework.core.KotlinDetector; -import org.springframework.data.redis.util.RedisAssertions; import org.springframework.data.util.Lazy; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -34,12 +33,14 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; import com.fasterxml.jackson.databind.module.SimpleModule; @@ -163,27 +164,55 @@ public class GenericJackson2JsonRedisSerializer implements RedisSerializer mapper.getSerializationConfig().getDefaultTyper(null) != null); - this.typeResolver = new TypeResolver(Lazy.of(mapper::getTypeFactory), - newTypeHintPropertyNameSupplier(mapper, typeHintPropertyName, this.defaultTypingEnabled)); + this.typeResolver = newTypeResolver(mapper, typeHintPropertyName, this.defaultTypingEnabled); } - private Supplier newTypeHintPropertyNameSupplier(ObjectMapper mapper, @Nullable String typeHintPropertyName, + private TypeResolver newTypeResolver(ObjectMapper mapper, @Nullable String typeHintPropertyName, Lazy defaultTypingEnabled) { - return typeHintPropertyName != null ? () -> typeHintPropertyName - : Lazy - .of(() -> defaultTypingEnabled.get() ? null - : mapper.getDeserializationConfig().getDefaultTyper(null) - .buildTypeDeserializer(mapper.getDeserializationConfig(), - mapper.getTypeFactory().constructType(Object.class), Collections.emptyList()) - .getPropertyName()) - .or("@class"); + Lazy lazyTypeFactory = Lazy.of(mapper::getTypeFactory); + + Lazy lazyTypeHintPropertyName = typeHintPropertyName != null ? Lazy.of(typeHintPropertyName) + : newLazyTypeHintPropertyName(mapper, defaultTypingEnabled); + + return new TypeResolver(lazyTypeFactory, lazyTypeHintPropertyName); + } + + private Lazy newLazyTypeHintPropertyName(ObjectMapper mapper, Lazy defaultTypingEnabled) { + + Lazy configuredTypeDeserializationPropertyName = getConfiguredTypeDeserializationPropertyName(mapper); + + Lazy resolvedLazyTypeHintPropertyName = Lazy.of(() -> defaultTypingEnabled.get() ? null + : configuredTypeDeserializationPropertyName.get()); + + resolvedLazyTypeHintPropertyName = resolvedLazyTypeHintPropertyName.or("@class"); + + return resolvedLazyTypeHintPropertyName; + } + + private Lazy getConfiguredTypeDeserializationPropertyName(ObjectMapper mapper) { + + return Lazy.of(() -> { + + DeserializationConfig deserializationConfig = mapper.getDeserializationConfig(); + + JavaType objectType = mapper.getTypeFactory().constructType(Object.class); + + TypeDeserializer typeDeserializer = deserializationConfig.getDefaultTyper(null) + .buildTypeDeserializer(deserializationConfig, objectType, Collections.emptyList()); + + return typeDeserializer.getPropertyName(); + }); } /** @@ -336,7 +365,8 @@ public class GenericJackson2JsonRedisSerializer implements RedisSerializer { - @Serial private static final long serialVersionUID = 1999052150548658808L; + @Serial + private static final long serialVersionUID = 1999052150548658808L; private final String classIdentifier;