目录
配置自定义RedisTemplate
引入依赖
配置连接redis
编写测试类
出现问题
配置序列化
解决redis序列化java8 LocalDateTime
问题背景
问题描述
问题分析
解决方案一(全局)
解决方案二(单个字段)
配置自定义RedisTemplate
引入依赖
<!-- redis -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.6.4</version>
</dependency>
配置连接redis
spring:redis: #配置redis连接host: 192.168.88.188port: 6379database: 0
编写测试类
然后就是写一个测试类,测一下Redis引入之后是否能过正常使用。新建文件RedisTest.java.
@RunWith(SpringRunner.class)
@SpringBootTest("com.jiamian.xxxxx")
public class RedisTest {@ResourceRedisTemplate redisTemplate;@Testpublic 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 {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {//创建RedisTemplate对象RedisTemplate<String, Object> 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
解决redis序列化java8 LocalDateTime
问题背景
目前项目全面支持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 解析 出错
解决方案一(全局)
引入依赖
<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.14.2</version>
</dependency>
RedisTemplateConfig 配置文件中修改如下
/*** 自定义序列化*/
@Configuration
public class RedisTemplateConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();redisTemplate.setConnectionFactory(connectionFactory);// key采用String的序列化方式redisTemplate.setKeySerializer(RedisSerializer.string());// hash的key也采用String的序列化方式redisTemplate.setHashKeySerializer(RedisSerializer.string());//创建Json序列化工具 ,支持jdk8 LocalDateTimeJackson2JsonRedisSerializer 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序列化方式采用jacksonredisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksonredisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}
解决方案二(单个字段)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
protected LocalDateTime createTime;