我使用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(),但是不起作用。有没有办法序列化\反序列化地图的整数键作为数字?
Jackson2JsonRedisSerializer
和GenericJackson2JsonRedisSerializer
都允许使用自定义ObjectMapper
。
不熟悉Redis,但似乎是根据doc设计的自定义序列化方式:
设置自定义配置的
ObjectMapper
是进一步控制JSON序列化过程的一种方法。例如,可以配置扩展的SerializerFactory
,为特定类型提供自定义序列化程序。改进序列化过程的另一个选项是使用Jackson提供的要序列化类型的注释,在这种情况下,不需要自定义配置的ObjectMapper。
通过在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<?> 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)));
}