Преобразование объекта, полученного от Redis, не выполняется с помощью class.cast и работает с использованием ObjectMapper.convertValue - PullRequest
1 голос
/ 08 марта 2019

В чем разница между использованием Class.cast для преобразования объекта в определенный тип v / s, делающим то же самое с использованием ObjectMapper.convertValue. Я предполагаю, что приведение также внутренне использует jackson, но я думаю, что это не так.

My RedisTemplateConfig:

@Bean
public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate(
    ReactiveRedisConnectionFactory factory) {
    StringRedisSerializer keySerializer = new StringRedisSerializer();
    Jackson2JsonRedisSerializer<Object> valueSerializer =
        new Jackson2JsonRedisSerializer<>(Object.class);
    RedisSerializationContext.RedisSerializationContextBuilder<String, Object> builder =
        RedisSerializationContext.newSerializationContext(keySerializer);
    RedisSerializationContext<String, Object> context =
        builder.value(valueSerializer).build();

    return new ReactiveRedisTemplate<>(factory, context);
}

SetValueInRedis:

@Override
public <T> Mono<T> setValue(String key, Object value, Class<T> clazz) {
    return reactiveValueOps.set(key, value,
            Duration.ofDays(SESSION_PERSISTENCE_DURATION))
            .map(o -> clazz.cast(value));
}

Рабочая GetValueInRedis:

@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
        return reactiveValueOps.get(key)
            .flatMap(val -> Mono.justOrEmpty(objectMapper.convertValue(val, clazz)));
}

Ошибка версии Get Value:

@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
    return reactiveValueOps.get(key)
        .flatMap(o -> Mono.justOrEmpty(clazz.cast(o)));
    }

---- EDIT ----

Если мы заметили сериализатор, используемый для Redis (Jackson2JsonRedisSerializer): при сохранении объекта в redis он работает нормально. Но при чтении (get) cast не получается и objectMappper работает. Когда я использую сериализатор Jackson2JsonRedis, не должна ли команда get возвращать объект, который должен быть преобразован с помощью самой команды Class.cast?

1 Ответ

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

Class.cast и ObjectMapper.convertValue - два совершенно разных механизма. Class.cast не создает новый объект, только возвращает старую ссылку с новым типом. Ниже вы можете увидеть, как реализовано Class.cast:

public T cast(Object obj) {
    if (obj != null && !isInstance(obj))
        throw new ClassCastException(cannotCastMsg(obj));
    return (T) obj;
}

Jackson с другой стороны создает новый объект из другой иерархии и копирует внутреннюю структуру. Например, можно преобразовать Map в POJO и POJO в Map, используя отражение. Но вы не можете разыграть ссылку на Map на ссылку на POJO.

Резюме: только convertValue метод из этих двух действительно выполняет преобразование из одного экземпляра в новый и из одного типа в новый. cast только пытается изменить тип ссылки на тот же объект.

Смотри также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...