问题描述
公司里需要用到单点登录,因为是springcloud微服务,最方便的方式就是将已登录的用户session数据统一存储到redis中,其他服务的登录状态直接在redis去取就行了,但是公司的业务模块分的比较细,用户是一个服务,订单是一个服务,商品服务又是一个服务;这就导致了我在用户服务登录后,拿token去订单服务校验时取不到redis的数据,
定位问题
通过debug发现,redis的序列化策略有3种
- JDK序列化 (默认序列化格式,耗时长、可能出现乱码)
- String序列化,耗时最短,string序列化后,可视化界面还是原样子,但是如果是对象的话,需要自己手动转为对象
- json序列化,官方实现的是jackson的序列化,此外fastjson也有对应的实现。优点是以键值对方式呈现,可读性好,但是对于hash类型的数据耗时较长
并且可以给key和value都设置不同的序列化方式,
知道这些就可以知道,原来就是我在A服务使用的是String序列化,而在B服务中,用的是JDK序列化,使用了2种不同的序列化方式,自然拿不到数据;所以需要统一序列化方式;
解决方案
现在知道问题,那就着手解决呗,其实也很简单,只需要在每个类种都加一个配置就可以了
package com.bizzan.bitrade.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
@Configuration
public class RedisCacheConfig {
/**
* RedisTemplate配置
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
//定义key序列化方式
//RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
//定义value的序列化方式
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// template.setKeySerializer(redisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}