Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用class.cast转换从Redis接收的对象失败,使用ObjectMapper.convertValue工作_Java_Json_Spring Boot_Jackson - Fatal编程技术网

Java 使用class.cast转换从Redis接收的对象失败,使用ObjectMapper.convertValue工作

Java 使用class.cast转换从Redis接收的对象失败,使用ObjectMapper.convertValue工作,java,json,spring-boot,jackson,Java,Json,Spring Boot,Jackson,使用Class.cast将对象转换为特定类型与使用ObjectMapper.convertValue执行相同操作有什么区别。 我假设cast内部也使用了jackson,但我认为这里的情况并非如此 我的RedisTemplateConfig: @Bean public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate( ReactiveRedisConnectionFactory factory) {

使用
Class.cast
将对象转换为特定类型与使用
ObjectMapper.convertValue
执行相同操作有什么区别。 我假设cast内部也使用了
jackson
,但我认为这里的情况并非如此

我的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);
}
@Bean
公共反应器模板反应器模板(
反应器(连接工厂){
StringRedisSerializer keySerializer=新的StringRedisSerializer();
Jackson2JsonRedisSerializer valueSerializer=
新的jackson2json重新序列化程序(Object.class);
RedisSerializationContext.RedisSerializationContextBuilder生成器=
newSerializationContext(keySerializer);
重新序列化上下文=
value(valueSerializer.build();
返回新的ReactiveRedisTemplate(工厂、上下文);
}
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));
}
@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
        return reactiveValueOps.get(key)
            .flatMap(val -> Mono.justOrEmpty(objectMapper.convertValue(val, clazz)));
}
@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
    return reactiveValueOps.get(key)
        .flatMap(o -> Mono.justOrEmpty(clazz.cast(o)));
    }
@覆盖
公共Mono setValue(字符串键、对象值、类clazz){
返回reactiveValueOps.set(键、值、,
持续时间天数(会话\持续时间\持续时间))
.map(o->clazz.cast(value));
}
工作GetValueInRedis:

@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));
}
@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
        return reactiveValueOps.get(key)
            .flatMap(val -> Mono.justOrEmpty(objectMapper.convertValue(val, clazz)));
}
@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
    return reactiveValueOps.get(key)
        .flatMap(o -> Mono.justOrEmpty(clazz.cast(o)));
    }
@覆盖
公共值(字符串键,类clazz){
返回reactiveValueOps.get(键)
.flatMap(val->Mono.justOrEmpty(objectMapper.convertValue(val,clazz));
}
获取值的错误版本:

@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));
}
@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
        return reactiveValueOps.get(key)
            .flatMap(val -> Mono.justOrEmpty(objectMapper.convertValue(val, clazz)));
}
@Override
public <T> Mono<T> getValue(String key, Class<T> clazz) {
    return reactiveValueOps.get(key)
        .flatMap(o -> Mono.justOrEmpty(clazz.cast(o)));
    }
@覆盖
公共值(字符串键,类clazz){
返回reactiveValueOps.get(键)
.flatMap(o->Mono.justOrEmpty(clazz.cast(o));
}
----编辑---


如果我们注意到用于Redis的序列化程序(
Jackson2JsonRedisSerializer
):将对象保存到Redis时,它工作正常。但是,在读取(get)
cast
时失败,
objectmapper
工作。当我使用
Jackson2JsonRedis
序列化程序时,
get
命令不应该返回一个应该可以使用Class.cast命令本身强制转换的对象吗?

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
方法才能真正实现从一个实例到新实例以及从一种类型到新类型的转换<代码>强制转换仅尝试将引用类型更改为同一对象

另见:


如果您注意到用于Redis的序列化程序,在将对象保存到Redis时,它可以正常工作。但是当读取cast失败并且对象映射器工作时。当我使用Jackson2JsonRedis序列化程序时,
get
命令不应该返回一个应该可以使用Class.cast命令强制转换的对象吗?谢谢。我理解ObjectMapper convertValue工作的原因,因为它试图从传递的对象创建一个新对象。但Redis序列化程序是否应该这样做,从而使我的对象可转换?还是我遗漏了什么?@Karshit,什么
reactiveValueOps.get(key)
方法返回?为什么我们需要
flatMap
。我从未使用过
Redis
,只是想解释
Class.cast
ObjectMapper.convertValue
之间的区别。如果您认为不应该转换任何内容,请使用
redis
标记创建新问题,并询问您为什么需要这样做。现在我没有太多关于您的项目的信息和关于
Redis
的知识来给您提供好的答案。