Redis缓存地图

问题描述 投票:0回答:2

我使用redis缓存并面临问题:带有整数键的map序列化为String,如下所示:

 "1":"AAAA","2":"BBB","3":"CCC"

这是我的配置的样子:

@Bean
    public RedisCacheConfiguration myCacheConfiguration()
    {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ZERO)
                .disableCachingNullValues()
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new Jackson2JsonRedisSerializer<>(Map.class)));
    }

  @Bean
    public CacheManager myCacheManager(RedisConnectionFactory redisConnectionFactory)
    {
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(myCacheConfiguration())
                .transactionAware()
                .build();
    }

我试图将GenericJackson2JsonRedisSerializer传递给serializeValuesWith(),但是不起作用。有没有办法序列化\反序列化地图的整数键作为数字?

java spring redis spring-data-redis jsonserializer
2个回答
1
投票

Jackson2JsonRedisSerializerGenericJackson2JsonRedisSerializer都允许使用自定义ObjectMapper

不熟悉Redis,但似乎是根据doc设计的自定义序列化方式:

设置自定义配置的ObjectMapper是进一步控制JSON序列化过程的一种方法。例如,可以配置扩展的SerializerFactory,为特定类型提供自定义序列化程序。改进序列化过程的另一个选项是使用Jackson提供的要序列化类型的注释,在这种情况下,不需要自定义配置的ObjectMapper。


0
投票

通过在Jackson2JsonRedisSerializer中添加方法JavaType getJavaType(Class clazz)的覆盖,可以轻松解决该问题。文件说:

/**
     * Returns the Jackson {@link JavaType} for the specific class.
     * <p>
     * Default implementation returns {@link TypeFactory#constructType(java.lang.reflect.Type)}, but this can be
     * overridden in subclasses, to allow for custom generic collection handling. For instance:
     *
     * <pre class="code">
     * protected JavaType getJavaType(Class&lt;?&gt; clazz) {
     *  if (List.class.isAssignableFrom(clazz)) {
     *      return TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, MyBean.class);
     *  } else {
     *      return super.getJavaType(clazz);
     *  }
     * }
     * </pre>
     *
     * @param clazz the class to return the java type for
     * @return the java type
     */
    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }

所以,我只是像这样重写这个方法:

public class CustomSerializer extends Jackson2JsonRedisSerializer
{
    public JurisdictionsSerializer(Class type)
    {
        super(type);
    }


    @Override
    protected JavaType getJavaType(Class clazz)
    {
        return TypeFactory.defaultInstance()
                .constructMapType(Map.class, Integer.class, String.class);
    }
}

然后将此序列化程序添加到redis配置中,如下所示:

@Bean
    public RedisCacheConfiguration myCacheConfiguration()
    {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ZERO)
                .disableCachingNullValues()
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new CustomSerializer(Map.class)));
    }
© www.soinside.com 2019 - 2024. All rights reserved.