Redis кэширует карту <Integer, String> - PullRequest
0 голосов
/ 21 марта 2019

Я использую кеш redis и столкнулся с проблемой: карта с целочисленным ключом сериализуется как строка так:

 "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 (), но это не работает.Есть ли способ сериализации \ десериализации целочисленных ключей карты как числа?

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Jackson2JsonRedisSerializer и GenericJackson2JsonRedisSerializer позволяют использовать пользовательские ObjectMapper.

Не знаком с Redis, но, похоже, он разработан для пользовательской сериализации в соответствии с doc :

Настройка пользовательских настроек ObjectMapper - это один из способов дальнейшего развития. управление процессом сериализации JSON. Например, расширенный SerializerFactory может быть настроен для предоставления пользовательских сериализаторов для конкретных типов. Другой вариант для уточнения сериализации Процесс должен использовать предоставленные Джексоном аннотации на типы, которые будут сериализованный, в этом случае настраиваемый объект ObjectMapper нет необходимости.

0 голосов
/ 22 марта 2019

Эта проблема легко решается добавлением переопределения метода JavaType getJavaType (Class clazz) в Jackson2JsonRedisSerializer.Документация гласит:

<code>/**
     * 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);
     *  }
     * }
     * 
* * @param clazz класс для возврата java-типа для * @ return java-типа * / protected JavaType getJavaType (Classclazz) {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)));
    }
...