項目中使用redis做緩存序列化踩坑
示例代碼
自定義的RedisTemplate,核心序列化器為GenericJackson2JsonRedisSerializer,其中使用了 jackson 來將對象轉為 json 字符串。
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
public class ObjectRedisTemplate extends RedisTemplate<String, Object> {
public ObjectRedisTemplate() {
RedisSerializer<Object> objectRedisSerializer = new GenericJackson2JsonRedisSerializer();
setKeySerializer(RedisSerializer.string());
setValueSerializer(objectRedisSerializer);
setHashKeySerializer(RedisSerializer.string());
setHashValueSerializer(objectRedisSerializer);
}
public ObjectRedisTemplate(RedisConnectionFactory connectionFactory) {
this();
setConnectionFactory(connectionFactory);
afterPropertiesSet();
}
protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
return new DefaultStringRedisConnection(connection);
}
}
問題描述
項目中使用了自定義的 RedisTemplate,redis中值的序列化方式為 json,但是包含了類名,生成的 json 如下
{
"@class": "com.imooc.User",
"userName": "lisi",
"address": {
"@class": "com.imooc.Address",
"province": "山東"
}
}
- 如果 A 服務將 User 對象保存到 redis 中,但是 User 類增加了字段,這個時候 B 服務從 redis 讀取會報錯,默認是不忽略不認識的屬性。
- 如果兩個服務的 User 類所屬的 package 不同,也會讀取 redis 失敗
擴展性很不好
解決方法
使用 Spring 中定義好的 StringRedisTemplate,它使用的序列化器為 StringRedisSerializer,我們在存到 redis 之前需要先自己將 Bean 對象轉為 json 字符串(自已控制)。這樣 redis 中存儲的就是簡單的 json 字符串,讀取也不會有亂七八糟的問題。

浙公網安備 33010602011771號