Redis序列化存储及日期格式的问题处理
这篇文章主要介绍了Redis序列化存储及其日期格式的问题处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
目录
Redis序列化存储及日期格式
可视化界面看到保存的数据是这样的
这时候就需要我们自定义序列化方式
Redis序列化LocalDateTime报错
方案一:实体类日期字段添加注解
方案二:设置Redis对日期序列化处理
Redis序列化存储及日期格式
在模块开发中,使用Redis做缓存是非常常见的技术,当我们注入RedisTempate模板时
1 | redisTemplate.opsForValue().set( "item_" +id,itemModel, 10 , TimeUnit.MINUTES); |
key我们可以用固定开头和商品id进行拼接,当然正常的项目开发中最好使用多级目录进行分类,这里只做演示使用
可视化界面看到保存的数据是这样的
这样的数据是很不容易阅读的,原因是Redis默认使用的是JAVA序列化方式,在序列化时使用了Redis协议中的编码。
不过在这种痛苦的数据面前做调试等工作无疑是非常不舒服的
这时候就需要我们自定义序列化方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @Configuration public class RedisConfig { /** * 修改Redis默认的序列化方式,默认文件在RedisAutoConfiguration * @param redisConnectionFactory * @return */ @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(redisConnectionFactory); //设置key的序列化方式为string StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); //设置value的序列化方式为json Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object. class ); //定制化关于时间格式序列化问题 ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(DateTime. class , new JodaDateTimeJsonSerializer()); simpleModule.addDeserializer(DateTime. class , new JodaDateTimeJsonDeSerializer()); objectMapper.registerModule(simpleModule); //在保存结果中加入类信息,方便解析数据 objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); return redisTemplate; } } |
1 2 3 4 5 6 | public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> { @Override public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(value.toString( "yyyy-MM-dd HH:mm:ss" )); } } |
1 2 3 4 5 6 7 8 | public class JodaDateTimeJsonDeSerializer extends JsonDeserializer<DateTime> { @Override public DateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { String s = p.readValueAs(String. class ); DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss" ); return DateTime.parse(s,dateTimeFormatter); } } |
Redis序列化LocalDateTime报错
实体类日期字段使用LocalDateTime,在Redis序列化时报错,会往Redis中写入如下数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | "createTime" : { "date" : { "year" : 2019, "month" : "MAY" , "day" : 15, "prolepticMonth" : 24232, "era" : [ "java.time.chrono.IsoEra" , "CE" ], "dayOfYear" : 135, "dayOfWeek" : "WEDNESDAY" , "leapYear" : false , "dayOfMonth" : 15, "monthValue" : 5, "chronology" : { "id" : "ISO" , "calendarType" : "iso8601" } }, "time" : { "hour" : 11, "minute" : 3, "second" : 43, "nano" : 758000000 }, "dayOfYear" : 135, "dayOfWeek" : "WEDNESDAY" , "month" : "MAY" , "dayOfMonth" : 15, "year" : 2019, "monthValue" : 5, "hour" : 11, "minute" : 3, "second" : 43, "nano" : 758000000, "chronology" : [ "java.time.chrono.IsoChronology" , { "id" : "ISO" , "calendarType" : "iso8601" } ] } |
方案一:实体类日期字段添加注解
每个LocalDateTime类型字段都需要添加,不建议使用
1 2 3 | @JsonDeserialize (using = LocalDateTimeDeserializer. class ) @JsonSerialize (using = LocalDateTimeSerializer. class ) private LocalDateTime birthday; |
方案二:设置Redis对日期序列化处理
添加配置:
1 2 3 4 5 | // 日期序列化处理 om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); om.registerModule( new Jdk8Module()) .registerModule( new JavaTimeModule()) .registerModule( new ParameterNamesModule()); |
完整配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); // 配置连接工厂 template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式) Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object. class ); ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jacksonSeial.setObjectMapper(om); // 值采用json序列化 template.setValueSerializer(jacksonSeial); //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer( new StringRedisSerializer()); // 设置hash key 和value序列化模式 template.setHashKeySerializer( new StringRedisSerializer()); template.setHashValueSerializer(jacksonSeial); template.afterPropertiesSet(); // 日期序列化处理 om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); om.registerModule( new Jdk8Module()) .registerModule( new JavaTimeModule()) .registerModule( new ParameterNamesModule()); return template; } } |
以上为个人经验,希望能给大家一个参考
原文链接:https://blog.csdn.net/qq_15038565/article/details/108418122