Сконфигурируйте новый сериализатор для конфигурации кэша redis при начальной загрузке - PullRequest
1 голос
/ 10 марта 2019

Я пытался изменить сериализатор по умолчанию для кеша redis с загрузочной пружиной, потому что я хочу перейти с Default на одну из реализаций Jackson2Json. Есть две реализации из библиотеки Jackson2Json, одной из которых является: GenericJackson2JsonRedisSerializer, которую я могу использовать в следующих экземплярах bean-компонента:

@Bean
@Primary
public RedisCacheConfiguration defaultCacheConfig(ObjectMapper objectMapper) {

    return RedisCacheConfiguration.defaultCacheConfig()
        .serializeKeysWith(
            SerializationPair.fromSerializer(
                new StringRedisSerializer()
            )
        )
        .serializeValuesWith(
            SerializationPair.fromSerializer(
                new GenericJackson2JsonRedisSerializer(objectMapper)
            )
        )
        .prefixKeysWith("");
}

Когда я использую этот сериализатор, сериализация работает нормально, все хранится на сервере Redis, но когда я пытаюсь десериализовать JSON, хранящийся на сервере Redis, я получаю следующее исключение:

java.util.LinkedHashMap cannot be cast to tutorial.Person with root cause

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to tutorial.Person

Кеш используется следующим образом:

@Cacheable(cacheNames = "person", key = "'person:'.concat(#post.id)")
public Person findPostAuthor(Post post){
}

Сериализатор не знает, как преобразовать LinkedHashMap в Person, как я могу сказать ему, как это сделать?

Другой сериализатор, с которым я пытался работать, был Jackson2JsonRedisSerializer:

@Bean
@Primary
public RedisCacheConfiguration defaultCacheConfig(ObjectMapper objectMapper) {
    Jackson2JsonRedisSerializer<Person> serializer = new Jackson2JsonRedisSerializer<>(Person.class);
    serializer.setObjectMapper(objectMapper);
    return RedisCacheConfiguration.defaultCacheConfig()
        .serializeKeysWith(
            SerializationPair.fromSerializer(
                new StringRedisSerializer()
            )
        )
        .serializeValuesWith(
            SerializationPair.fromSerializer(
                serializer
            )
        )
        .prefixKeysWith("");
}

На этом пути мне придется объявлять bean-компонент для каждого объекта, сохраненного в кэше Redis, но я могу правильно сериализовать / десериализовать.

Когда я вставляю JSON непосредственно в кеш redis, я не могу десериализовать его с помощью этого сериализатора, и сериализатор просто дает мне объект Person с пустыми свойствами name, email и id. Есть ли способ это исправить?

Если есть способ улучшить мой вопрос, пожалуйста, дайте мне знать.

1 Ответ

3 голосов
/ 11 марта 2019

GenericJackson2JsonRedisSerializer предполагает, что Джексон набирает по умолчанию .Когда вы создаете GenericJackson2JsonRedisSerializer с экземпляром ObjectMapper, убедитесь, что вы настроили типизацию по умолчанию (enableDefaultTyping(…)).

Типизация по умолчанию лучше всего работает с неконечными типами и требует согласованного имени свойства для типа во всех полезных нагрузках JSON, чтобы Джексон мог определить подходящий тип для десериализации.

Типизация по умолчанию использует динамическийвведите маркер, и если ваш источник данных (экземпляр Redis) не является полностью доверенным, это может стать проблемой безопасности.

Jackson2JsonRedisSerializer прикреплен к определенному типу и устраняет риск динамической типизации.

...