Skip to content

Support deserialization in GenericJackson2JsonRedisSerializer when using custom JsonFactory #2981

Closed
@housevenn

Description

@housevenn

We create RedisCacheConfiguration with value serializer like this:

        RedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer(new ObjectMapper(new MessagePackFactory()));
        RedisCacheConfiguration redisCacheConfig = RedisCacheConfiguration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer));

It uses an ObjectMapper with a custom JsonFactory (MessagePackFactory). Serialization works correctly, but deserialization encounters the following exception:

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('²' (code 178)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 1]
at com.fasterxml.jackson.core.JsonParser._constructReadException(JsonParser.java:2643)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:685)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2750)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:867)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:753)
at com.fasterxml.jackson.databind.ObjectMapper._readTreeAndClose(ObjectMapper.java:4934)
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:3294)
at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer$TypeResolver.resolveType(GenericJackson2JsonRedisSerializer.java:363)
at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.resolveType(GenericJackson2JsonRedisSerializer.java:337)
at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:304)
at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:276)
at com.coupang.storageservice.redis.spring.data.sdk.serializer.GzipRedisSerializer.deserialize(GzipRedisSerializer.java:54)
at org.springframework.data.redis.serializer.DefaultRedisElementReader.read(DefaultRedisElementReader.java:46)
at org.springframework.data.redis.serializer.RedisSerializationContext$SerializationPair.read(RedisSerializationContext.java:277)
at org.springframework.data.redis.cache.RedisCache.deserializeCacheValue(RedisCache.java:386)
at org.springframework.data.redis.cache.RedisCache.lookup(RedisCache.java:209)

The error happens on this line at resolveType. The cause is that TypeResolver uses a default ObjectMapper which would throw exception here during deserialization when the value is serialized by our ObjectMapper with custom JsonFactory as shown above. The default ObjectMapper uses MappingJsonFactory in comparison.

Solution: when creating the TypeResolver here, we should use the ObjectMapper which was passed in here, and store it on the TypeResolver to use. Or at least make that an option so we can use it to avoid the deserialization error. I have tested that it can fix the deserialization issue, but not sure if there is any other implication.

FYI, our code was working fine with spring-data-redis 2.7.x but encountered this issue now as we are upgrading to spring-data-redis 3. It's because of this commit which changed the deserialization function and added resolveType.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions