【Redis】redisTemplate序列化配置、解决LocalDateTime数据类型序列化报错问题、解决无法自动装配问题

阅读: 评论:0

【Redis】redisTemplate序列化配置、解决LocalDateTime数据类型序列化报错问题、解决无法自动装配问题

【Redis】redisTemplate序列化配置、解决LocalDateTime数据类型序列化报错问题、解决无法自动装配问题

文章目录

  • 文章目录
  • 正文
  • 一、导入依赖
  • 二、创建RedisTemplate的配置类
  •         1. 基础配置
  •         2. 配置序列化工具,解决LocalDateTime序列化问题
  • 三、完整代码
  • 四、无法自动装配解决办法

正文

一、导入依赖

        这里使用jackson依赖,用其他的序列化工具也可

<!-- redis -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!-- jackson -->
<dependency><groupId>com.</groupId><artifactId>jackson-databind</artifactId>
</dependency>

二、创建RedisTemplate的配置类

        1. 基础配置

@Configuration
public class RedisTemplateConfig {@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 创建redisTemplate对象RedisTemplate<Object, Object> template = new RedisTemplate<>();// 连接工厂template.setConnectionFactory(redisConnectionFactory);// 获取序列化工具StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);// 设置key的序列化 (Redis 默认序列化工具)template.setKeySerializer(stringRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);// 设置value的序列化 (Jackson 序列化工具)template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);// 开启事务template.setEnableTransactionSupport(true);return template;}
}

         上述配置就可以满足基本需求,但当java实体类含有LocalDateTime数据类型时会报错:org.dis.serializer.SerializationException: Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module

         因此需要配置序列化工具,使其支持对该数据类型的序列化与反序列化

        2. 配置序列化工具,解决LocalDateTime序列化问题

private GenericJackson2JsonRedisSerializer myJasonRedisSerializer() {ObjectMapper objectMapper = new ObjectMapper();// 设置可见性objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 序列化后添加类信息(不配置,序列化后就是一个Json字符串)objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);// 将日期序列化为可读字符串而不是时间戳objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);//设置时间模块(格式化,不设置,则输出默认格式)JavaTimeModule timeModule = new JavaTimeModule();// LocalDateTimetimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"))));timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"))));// LocalDatetimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Shanghai"))));timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Shanghai"))));// 设置自定义时间模块isterModule(timeModule);return new GenericJackson2JsonRedisSerializer(objectMapper);
}

        注: 

1.  objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); 会在序列化后带上类的信息,便于反序列化。 

2.  解决序列化LocalDateTime数据类型报错: 

        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        isterModule(new JavaTimeModule());


三、完整代码

代码如下:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import t.annotation.Bean;
import t.annotation.Configuration;
import org.tion.RedisConnectionFactory;
import org.RedisTemplate;
import org.dis.serializer.Jackson2JsonRedisSerializer;
import org.dis.serializer.StringRedisSerializer;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;@Configuration
public class RedisTemplateConfig {@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 创建redisTemplate对象RedisTemplate<Object, Object> template = new RedisTemplate<>();// 连接工厂template.setConnectionFactory(redisConnectionFactory);// 获取序列化工具StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = JasonRedisSerializer();// 设置key的序列化 (Redis 默认序列化工具)template.setKeySerializer(stringRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);// 设置value的序列化 (Jackson 序列化工具)template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);// 开启事务template.setEnableTransactionSupport(true);return template;}private Jackson2JsonRedisSerializer<Object> myJasonRedisSerializer() {ObjectMapper objectMapper = new ObjectMapper();// 设置可见性objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 序列化后添加类信息(不配置,序列化后就是一个Json字符串)objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);// 将日期序列化为可读字符串而不是时间戳objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);// 设置时间模块(格式化,不设置,则输出默认格式)JavaTimeModule timeModule = new JavaTimeModule();// LocalDateTimetimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"))));timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"))));// LocalDatetimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Shanghai"))));timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Shanghai"))));// 设置自定义时间模块isterModule(timeModule);return new Jackson2JsonRedisSerializer<>(objectMapper, Object.class);}
}

四、无法自动装配解决办法

        写好配置,但在写项目时却遇到了:无法自动装配,找不到 'RedisTemplate<Object, String>' 类型的 Bean的报错问题,通过查阅资料(秋日的晚霞 - springboot整合redisTemplate 自动装配失败原因)找到了解决办法:

        如果使用 @Autowired(按类型装配) 进行自动装配,那么RedisTemplate就不要指定泛型,或者将泛型指定为<Stirng,String> 或者<Object,Object>;(我就在这卡了很久。。)

        而如果想要指定泛型例如<String,Object>,那么就需要使用 @Resource(按bean名称装配) 来进行自动装配。

本文发布于:2024-01-29 16:53:36,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170651841716789.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23