1.反序列化复杂对象应该注意的事情
使用 JSON.parseObject(jsonString,MyModel.class); 反序列化复杂对象时,包含的属性类必须有无参的构造方法,否则容易出现丢失属性的的问题;
2.使用Redis作为缓存时 可以自定义序列化方法
好处:可以直接查看缓存内容,不容易出现 ClassCastException 异常
自定义序列化实现类如下:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/**
* 说明:自定义redis序列化方式 防止 @Cacheabl 注解不能用(会报类转换异常)
*/
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
static {
//使用Redis 配置替换fastjson 反序列化报错 com.alibaba.fastjson.JSONException: autoType is not support
//加入白名单就好了
ParserConfig.getGlobalInstance().addAccept("com.xxx.xxx");
}
public FastJsonRedisSerializer(Class<T> clazz){
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException{
if(t ==null){
return new byte[0];
}
return JSON.toJSONString(t,SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes)throws SerializationException{
if(bytes ==null|| bytes.length <=0){
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
}
使用时 给 RedisCacheConfiguration 设置序列化方式即可(多数在 @Bean 方法体内添加修改即可)
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//自定义序列化方式(默认的序列化方式无法查看redis中的Val 经常会出现类转换异常)
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new FastJsonRedisSerializer<>(Object.class)));
3.使用时正常使用缓存即可
@Cacheable(value = {"cache_1min"}, key = "'summary:' + #query.code + ':' + #query.code + ':' + #query.dimension ")
public summary query(SearchBase query)
4.一个比较简单的缓存Key自动生成策略
/**
* 缓存 @Cacheable key 自动生成策略
* @return
*/
@Bean
public KeyGenerator customKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getSimpleName()).append(":");
sb.append(method.getName()).append(":");
if(null!=params){
if(params instanceof Object[]){
sb.append(StringUtils.arrayToCommaDelimitedString(params));
}else{
sb.append(StringUtils.arrayToCommaDelimitedString(new Object[]{params}));
}
}else{
sb.append("no_params");
}
return sb.toString();
};
}
//使用方式 @Cacheable(value = {"cache_value"}, keyGenerator = "customKeyGenerator")