目录
配置自定义RedisTemplate
引入依赖
配置连接redis
编写测试类
出现问题
配置序列化
解决redis序列化java8 LocalDateTime
问题背景
问题描述
问题分析
解决方案一(全局)
解决方案二(单个字段)
org.springframework.boot
spring-boot-starter-data-redis
2.6.4
spring:
redis: #配置redis连接
host: 192.168.88.188
port: 6379
database: 0
然后就是写一个测试类,测一下Redis引入之后是否能过正常使用。新建文件RedisTest.java.
@RunWith(SpringRunner.class)
@SpringBootTest("com.jiamian.xxxxx")
public class RedisTest {
@Resource
RedisTemplate redisTemplate;
@Test
public void test(){
//操作string类型的 操作对象
ValueOperations valueOperations = redisTemplate.opsForValue();
//增
valueOperations.set("jiamian_string","str123");
valueOperations.set("jiamian_Integer",1);
valueOperations.set("jiamian_Double",2.0);
User user = new User();
user.setId(0L);
user.setUsername("加棉");
valueOperations.set("jiamian_User",user);
//查
Object jiamian_string = valueOperations.get("jiamian_string");
Object jiamian_Integer = valueOperations.get("jiamian_Integer");
Object jiamian_Double = valueOperations.get("jiamian_Double");
Object jiamian_User = valueOperations.get("jiamian_User");
System.out.println(jiamian_string);
System.out.println(jiamian_Integer);
System.out.println(jiamian_Double);
System.out.println(jiamian_User);
}
}
去redis-cli客户端中查看发现存入的key和我们想象中的不同,这里的序列编码有问题。这是因为RedisTemplate默认使用了jdk序列化器。
如果操作的key和value都是string类型,可以使用StringRedisTemplate进行操作。
StringTemplate部分源码如下:
因为我们这里存的值有多种类型,我们就使用自定义的序列化器
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
//创建RedisTemplate对象
RedisTemplate redisTemplate = new RedisTemplate<>();
//设置连接工厂
redisTemplate.setConnectionFactory(connectionFactory);
//设置Key的序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
//创建Json序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//设置Value的序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
}
在QuickRedis中查看,问题解决!!!
后续会出现的问题:
如何实体类中有LocalDateTime类型的属性,在redis序列化时会报以下错误.
Redis序列化 jdk8 LocalDateTime问题
org.springframework.data.redis.serializer.SerializationException: Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
目前项目全面支持JDK1.8,使用 LocalDateTime 代替 Date,原因为 date 格式化时不安全。
org.springframework.data.redis.serializer.SerializationException: Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
GenericJackson2JsonRedisSerializer 解析 出错
引入依赖
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
2.14.2
RedisTemplateConfig 配置文件中修改如下
/**
* 自定义序列化
*/
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(connectionFactory);
// key采用String的序列化方式
redisTemplate.setKeySerializer(RedisSerializer.string());
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(RedisSerializer.string());
//创建Json序列化工具 ,支持jdk8 LocalDateTime
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//LocalDatetime序列化
JavaTimeModule timeModule = new JavaTimeModule();
timeModule.addDeserializer(LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
timeModule.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(timeModule);
jackson2JsonRedisSerializer.setObjectMapper(om);
// value序列化方式采用jackson
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
protected LocalDateTime createTime;