首页 > 解决方案 > 如何使用 GenericJackson2JsonRedisSerializer

问题描述

我正在使用 Spring Data Redis 来缓存一些数据@Cacheable。我有多种类型的对象需要缓存,并且我需要来自 Redis 的数据为 JSON 格式。我知道,默认情况下,使用的序列化程序是JdkSerializationRedisSerializer,但是缓存的数据不是人类可读的。

我命令以我想要使用的 JSON 格式保存数据,GenericJackson2JsonRedisSerializer并且我也创建了一个自定义ObjectMapper

  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;

使用它RedisTemplate不起作用,我总是得到这个错误:

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

据我了解,在反序列化时,杰克逊不知道特定对象的类型,因为它Object创建了一个LinkedHashMap来保存数据。也许我对此有误,但是如何使用@Cacheble 将缓存数据保存为 JSON 以用于多种类型的对象?

标签: javaspringcachingredis

解决方案


你是对的,你可以用GenericJackson2JsonRedisSerializer. 但是在您的示例中,您提供自定义并且不为您配置ObjectMapperJackson的默认类型(您可以在 中检查默认构造函数逻辑)。您必须自己调整它并将其添加到您的 ObjectMapperGenericJackson2JsonRedisSerializerGenericJackson2JsonRedisSerializerGenericJackson2JsonRedisSerializer

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

这将包括 JSON 的类型信息。像这样

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

推荐阅读