Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
162 views
in Technique[技术] by (71.8m points)

java - How to use GenericJackson2JsonRedisSerializer

I am using Spring Data Redis in order to cache some data using @Cacheable. I have multiple types of objects that need to be cached and I need the data from Redis to be in JSON format. I know that, by default, the serializer used is JdkSerializationRedisSerializer, but with is the cached data is not human readable.

I order to save the data in JSON format I wanted to use GenericJackson2JsonRedisSerializer and I've created a custom ObjectMapper too:

  public RedisTemplate<Object, Object> redisTemplate (RedisConnectionFactory cf) {

    ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder().failOnEmptyBeans(false)
        .failOnUnknownProperties(false)
        .indentOutput(false)
        .serializationInclusion(JsonInclude.Include.NON_NULL)
        .modules(
            // Optional
            new Jdk8Module(),
            // Dates/Times
            new JavaTimeModule()
        )
        .featuresToDisable(
            SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
            DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,
            SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
        ).build();


    GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
    RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(cf);
    redisTemplate.setKeySerializer(genericJackson2JsonRedisSerializer);
    redisTemplate.setHashKeySerializer(genericJackson2JsonRedisSerializer);
    redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
    redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
    return redisTemplate;

Using this RedisTemplate doesn't work and I always get back this error:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to <some class>

As I understood, when deserializing, Jackson doesn't know the type of the specific object since it's Object and creates a LinkedHashMap to hold the data. Maybe I am wrong with this, but how can I achieve saving the cached data as JSON for multiple types of objects with @Cacheble?

question from:https://stackoverflow.com/questions/65886082/how-to-use-genericjackson2jsonredisserializer

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are right, you can achieve saving multiple types with GenericJackson2JsonRedisSerializer. But in your example, you provide custom ObjectMapper to GenericJackson2JsonRedisSerializer and GenericJackson2JsonRedisSerializer doesn't configure Jackson's default typing for you (you can check default constructor logic in GenericJackson2JsonRedisSerializer). You have to tune it on your own and add this to your ObjectMapper

objectMapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);

This will include type information to JSON. Like this

{
  "@class": "com.example.Foo",
  "field": "bar"
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...