DATAREDIS-865 - Expose GenericJackson2JsonRedisSerializer.registerNullValueSerializer() for ObjectMapper customization.
We now expose registerNullValueSerializer(…) on GenericJackson2JsonRedisSerializer to allow customization of an externally provided ObjectMapper. NullValueSerializer was previously registered only within a constructor that takes classPropertyTypeName and provided no further possibilities to customize ObjectMapper. Code wishing to provide a custom ObjectMapper can now call GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, …) and perform additional customizations before using ObjectMapper with GenericJackson2JsonRedisSerializer. Original Pull Request: #376
This commit is contained in:
committed by
Christoph Strobl
parent
ed79d14355
commit
1f4bb973ea
@@ -34,7 +34,10 @@ import com.fasterxml.jackson.databind.ser.SerializerFactory;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
/**
|
||||
* Generic Jackson 2-based {@link RedisSerializer} that maps {@link Object objects} to JSON using dynamic typing.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 1.6
|
||||
*/
|
||||
public class GenericJackson2JsonRedisSerializer implements RedisSerializer<Object> {
|
||||
@@ -61,7 +64,7 @@ public class GenericJackson2JsonRedisSerializer implements RedisSerializer<Objec
|
||||
|
||||
// simply setting {@code mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)} does not help here since we need
|
||||
// the type hint embedded for deserialization using the default typing feature.
|
||||
mapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer(classPropertyTypeName)));
|
||||
registerNullValueSerializer(mapper, classPropertyTypeName);
|
||||
|
||||
if (StringUtils.hasText(classPropertyTypeName)) {
|
||||
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
|
||||
@@ -83,6 +86,22 @@ public class GenericJackson2JsonRedisSerializer implements RedisSerializer<Objec
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link NullValueSerializer} in the given {@link ObjectMapper} with an optional
|
||||
* {@code classPropertyTypeName}. This method should be called by code that customizes
|
||||
* {@link GenericJackson2JsonRedisSerializer} by providing an external {@link ObjectMapper}.
|
||||
*
|
||||
* @param objectMapper the object mapper to customize.
|
||||
* @param classPropertyTypeName name of the type property. Defaults to {@code @class} if {@literal null}/empty.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static void registerNullValueSerializer(ObjectMapper objectMapper, @Nullable String classPropertyTypeName) {
|
||||
|
||||
// simply setting {@code mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)} does not help here since we need
|
||||
// the type hint embedded for deserialization using the default typing feature.
|
||||
objectMapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer(classPropertyTypeName)));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.serializer.RedisSerializer#serialize(java.lang.Object)
|
||||
@@ -140,7 +159,7 @@ public class GenericJackson2JsonRedisSerializer implements RedisSerializer<Objec
|
||||
* @author Christoph Strobl
|
||||
* @since 1.8
|
||||
*/
|
||||
private class NullValueSerializer extends StdSerializer<NullValue> {
|
||||
private static class NullValueSerializer extends StdSerializer<NullValue> {
|
||||
|
||||
private static final long serialVersionUID = 1999052150548658808L;
|
||||
private final String classIdentifier;
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.hamcrest.core.IsInstanceOf.*;
|
||||
import static org.hamcrest.core.IsNull.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.springframework.test.util.ReflectionTestUtils.*;
|
||||
import static org.springframework.util.ObjectUtils.*;
|
||||
|
||||
@@ -31,15 +32,20 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.cache.support.NullValue;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GenericJackson2JsonRedisSerializer}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class GenericJackson2JsonRedisSerializerUnitTests {
|
||||
|
||||
@@ -122,11 +128,28 @@ public class GenericJackson2JsonRedisSerializerUnitTests {
|
||||
new GenericJackson2JsonRedisSerializer(objectMapperMock).deserialize(new byte[] { 1 });
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-553
|
||||
@Test // DATAREDIS-553, DATAREDIS-865
|
||||
public void shouldSerializeNullValueSoThatItCanBeDeserializedWithDefaultTypingEnabled() {
|
||||
|
||||
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
|
||||
|
||||
serializeAndDeserializeNullValue(serializer);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-865
|
||||
public void shouldSerializeNullValueWithCustomObjectMapper() {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
|
||||
|
||||
GenericJackson2JsonRedisSerializer.registerNullValueSerializer(mapper, null);
|
||||
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(mapper);
|
||||
|
||||
serializeAndDeserializeNullValue(serializer);
|
||||
}
|
||||
|
||||
private static void serializeAndDeserializeNullValue(GenericJackson2JsonRedisSerializer serializer) {
|
||||
|
||||
NullValue nv = BeanUtils.instantiateClass(NullValue.class);
|
||||
|
||||
byte[] serializedValue = serializer.serialize(nv);
|
||||
|
||||
Reference in New Issue
Block a user