spring-data-redis java.lang.ClassCastException

Wil*_*Lei 1 java redis jedis spring-data

在我的测试项目中,我通过 spring-data-redis 和 jedis 构建了我的缓存系统。和valueSerializerRedisTemplateGenericJackson2JsonRedisSerializer。但这里有一个问题,当我从 java.lang.Long 类型的缓存中范围一个列表时,有一个java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long. 任何人都知道原因,它让我困惑了很长时间;

Redis 配置细节如下:

<bean id="objRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="connectionFactory" ref="redisConnectionFactory" />
    <property name="keySerializer">
        <bean
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    </property>
    <property name="valueSerializer">
        <bean
            class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

代码详情如下:

public List<Long> findByProductId(Long productId) {
    String key = ThemeRedisKeyGenerator.genProductThemeKey(productId);
    List<Long> themeIdList = redisService.range(key, Long.class);
    if (themeIdList == null) {
        themeIdList = themeProductMapper
                .selectThemeIdByProductId(productId);
        if (!redisService.containKey(key)) {
            redisService.rightPush(key,
                    ThemeRedisKeyGenerator.PRODUCT_THEME_KEY_EXPIRE_HOURS,
                    TimeUnit.HOURS, themeIdList.toArray());
        }
    }
    return themeIdList;
}
Run Code Online (Sandbox Code Playgroud)

而redis服务方法如下:

public <T> List<T> range(String key, Class<T> clazz) {
    return range(key, 0L, -1L, clazz);
}
public <T> List<T> range(String key, Long start, Long end, Class<T> clazz) {
    if (StringUtil.isEmpty(key) || !objRedisTemplate.hasKey(key)) {
        return null;
    }

    if (start < 0) {
        start = 0L;
    }

    List<T> list = (List<T>) (objRedisTemplate.opsForList().range(key,
            start, end));

    if(list == null) {
        list = new ArrayList<T>();
    }

    return list;
}
Run Code Online (Sandbox Code Playgroud)

mp9*_*1de 6

简而言之

默认情况下,int当数字小于 2 31 -1时,Jackson 返回

解释

JSON 的数据类型数量有限。也没有附加类型信息:

{
    "number": 42
}
Run Code Online (Sandbox Code Playgroud)

42可能是原本是shortintlong,但你不能从JSON告诉。默认设置是int在数字小于 时使用Integer.MAX_INT

您有多种选择来解决此问题:

  1. 使用Number作为接口的数据,回来
  2. 配置GenericJackson2JsonRedisSerializer通过提供一个配置ObjectMapper
  3. 使用使用类型详细信息的不同序列化程序(例如JdkSerializationRedisSerializer

您可以在此处找到有关 JSON 反序列化的更多详细信息。