spring-数据-redis java.lang.ClassCastException
spring-data-redis java.lang.ClassCastException
在我的测试项目中,我通过spring-data-redis和jedis构建了我的缓存系统。而RedisTemplate
的valueSerializer
是GenericJackson2JsonRedisSerializer
。但是这里有一个问题,当我从 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>
代码详情如下:
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;
}
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;
}
简而言之
默认情况下,Jackson returns int
当数字小于231-1
说明
JSON 数据类型数量有限。也没有附加类型信息:
{
"number": 42
}
42
原本可能是short
、int
或long
,但从JSON看不出来。如果数字小于 Integer.MAX_INT
,默认设置是使用 int
。
您有多种解决问题的方法:
- 使用
Number
作为返回数据的接口
- 通过提供已配置的
ObjectMapper
配置 GenericJackson2JsonRedisSerializer
- 使用使用类型详细信息的不同序列化程序(例如
JdkSerializationRedisSerializer
)
您可以找到有关 JSON 反序列化 here 的更多详细信息。
在我的测试项目中,我通过spring-data-redis和jedis构建了我的缓存系统。而RedisTemplate
的valueSerializer
是GenericJackson2JsonRedisSerializer
。但是这里有一个问题,当我从 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>
代码详情如下:
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;
}
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;
}
简而言之
默认情况下,Jackson returns int
当数字小于231-1
说明
JSON 数据类型数量有限。也没有附加类型信息:
{
"number": 42
}
42
原本可能是short
、int
或long
,但从JSON看不出来。如果数字小于 Integer.MAX_INT
,默认设置是使用 int
。
您有多种解决问题的方法:
- 使用
Number
作为返回数据的接口 - 通过提供已配置的
ObjectMapper
配置 - 使用使用类型详细信息的不同序列化程序(例如
JdkSerializationRedisSerializer
)
GenericJackson2JsonRedisSerializer
您可以找到有关 JSON 反序列化 here 的更多详细信息。