Spring Boot缓存Redis&&Jackson2JsonRedisSerializer反序列化
1 需求最近博客的音乐播放器出现了问题,无法获取到音乐的数据了,我才发现原来我以前用的不是网易官方的API(o(╥﹏╥)o),真是打了我一个措手不及啊。因为音乐播放器不是我自己写的(但还好为了适配我的网站我还是看了看它的代码,改了一部分接口),不知道数据格式是什么样的,只能自己看代码探索(也是绝了),所以难度系数增加了不少。2 寻找API首先面临的问题就是找到相关的API,我的需求是能返回我...
1 需求
最近博客的音乐播放器出现了问题,无法获取到音乐的数据了,我才发现原来我以前用的不是网易官方的API(o(╥﹏╥)o),真是打了我一个措手不及啊。因为音乐播放器不是我自己写的(但还好为了适配我的网站我还是看了看它的代码,改了一部分接口),不知道数据格式是什么样的,只能自己看代码探索(也是绝了),所以难度系数增加了不少。
2 寻找API
首先面临的问题就是找到相关的API,我的需求是能返回我歌单里面的所有歌曲的详细信息(包括歌曲名,歌手,封面图片,歌曲链接等信息
)。经过一番寻找,先是找到了别人提供的第三方的接口,可以获取到我所需要的信息,试了一下,音乐播放器又复活了。但是一方面因为再也不信任第三方的缘故,和速度问题,我还是决定使用官方的接口。又经过了一番寻找,摸索,终于找到了我需要的接口。因为没有接口能一次性满足我的要求,所以找到了两个替代接口。
2.1 获取歌单详细信息
http://music.163.com/api/playlist/detail?id=xxx
id为你歌单的id,如何找出你歌单的id,这个具体操作方法,你可以在网上找找,因为不是写这个,就不写这个方法了。接口返回结果如下:
2.2 获取歌曲链接
http://music.163.com/api/song/enhance/player/url?ids=["+id+"]&br=320000
id为歌曲的id,可以一次获取多个
,id之间使用逗号(,)分隔
。br为歌曲的品质,320000代表320K(这里需要注意的是,如果没有相应的品质或者需要VIP才能享受的,会默认返回180K
)。结果如下:
3 速度太慢
首先因为歌单中歌曲的数量很多,并且会一直增加,如果每次都向网易的接口那边请求数据,连接,读取,处理,传递,一连串的操作,我觉得速度非常的慢,完全不能忍受。还有就是返回的数据不是我所需求的格式,我还需要处理一下才返回给前端,这无疑不是又增加了开销吗!当然还有最重要的一个原因,请求太频繁,网易改接口了怎么办(我太难了o(╥﹏╥)o)。获取的数据不是立即需要更新的,需要重复使用,但是每次使用都要做一系列操作,导致速度慢
。套上这个场景,我第一时刻就想到了缓存
。
4 SpringBoot及Spring默认缓存(ConcurrentMapCache)
首先使用的是默认的缓存
,因为什么都不需要配置。了解一下注解使用缓存
4.1 使用注解开启缓存
4.2 使用@Cacheable注解
@Cacheable(value = "playList",key = "#id")
@RequestMapping("/music/getPlayList")
public Object getLikePlayList(String id){
}
SpEL表达式
其中value相当于文件夹(缓存的名称cacheName),key相当于文件夹下的文件名(这样在不同的value下存放key相同的值了)
4.3 新的问题
使用默认的存储虽说简单,不需要什么配置,但是所有的东西都交给了spring管理,我后台想看看缓存的数据都不方便,缓存又存储在服务器的内存中,这样以后缓存的数据越来越多,服务器还不炸了,还是让他们分开比较好。所以又想到了缓存的一把好手Redis
5 整合Redis使用缓存
5.1 配置文件
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=xxx
# Redis服务器连接端口
spring.redis.port=xxx
# Redis服务器连接密码(默认为空)
spring.redis.password=xxx
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000
5.2 Java类配置Redis对应配置
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
@Bean
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
//设置默认的过期时间(以秒为单位)
redisCacheManager.setDefaultExpiration(600);
//开启使用前缀,将会用冒号连接value和key,如果设置为false
//不同value,同key将会覆盖,不会出现上面的情况(注意)
redisCacheManager.setUsePrefix(true);
//设置缓存名称(按value)的过期时间(以秒为单位)
//redisCacheManager.setExpires();
//例子:
//Map<String, Long> timeToLiveMap = new HashMap<>(2);
//timeToLiveMap.put("playList",200L);
//timeToLiveMap.put("musicUrl",250L);
return redisCacheManager;
}
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}
5.3 Jackson2JsonRedisSerializer反序列化问题
按照下面这样写的话
@Cacheable(value = "playList",key = "#id")
@RequestMapping("/music/getPlayList")
public JsonArray getLikePlayList(String id){
....
return returnJsonArray;
}
会报转换异常
java.lang.ClassCastException: java.util.ArrayList cannot be cast to net.sf.json.JSONArray
因为从Redis中取出的数据是一个List数组,无法转换为我外部引入的JSONArray,那怎么解决了?
5.4 第一个方法
将JsonArray转换为String存储,就不存在转换问题
@Cacheable(value = "playList",key = "#id")
@RequestMapping("/music/getPlayList")
public String getLikePlayList(String id){
....
return returnJsonArray.toString();
}
5.5第二个方法
@Cacheable(value = "playList",key = "#id")
@RequestMapping("/music/getPlayList")
public Object getLikePlayList(String id){
....
return returnJsonArray;
}
存储在Redis中的是Json数组,从缓冲中拿出的时候转换为Object,直接返回
更多推荐
所有评论(0)