当前位置: 首页 > news >正文

Redis中储存含LocalDateTime属性对象的序列化实现

目录

1.问题1 向Redis中存入序列化对象

1.1引入 :

1.2解决方案:

1.2.1首先引入依赖

1.2.2然后在RedisConfig中进行配置

1.3 介绍下ObjectMapper

1.3.1  ObjectMapper

1.3.2  objectMapper.registerModule(new JavaTimeModule());

1.3.3  GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);

2 问题2 从Redis取出数据转换为Java对象

2.1 引入:

2.2 解决方案

3 序列化优点

4 objectMapper.convertValue()

4.1 原理

4.2 基本步骤

4.3 示例


1.问题1 向Redis中存入序列化对象

"Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default"

1.1引入 :

        在mysql中存储时间除了TimeStamp以外,常用的就是就是DateTime了,若在表中包含DateTime字段,对应的Java实体类属性常使用LocalDateTime类。

        LocalDateTime(包括LocalDate等常见类)Java 8 中引入的新时间和日期 API 中的类,属于 java.time 包,它提供了更强大的日期时间操作功能。Java 8 之前的 java.util.Date 和 java.util.Calendar 类在设计上有许多局限性,而 Java 8 通过引入 java.time 包,提供了更加直观和线程安全的日期时间处理类。

但需要注意:

        当类中包含 Java 8 的 LocalDateTime 类型属性时,无法直接将该类序列化为 JSON 并存储在 Redis 中,因为 LocalDateTime 是非标准的时间格式,JSON 序列化工具(例如 Jackson 或 Gson)无法直接处理这种类型。

若直接进行存储会出现如下错误:

        "Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default......"

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 (through reference chain: com.hspedu.seckill.pojo.User["registerDate"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.hspedu.seckill.pojo.User["registerDate"]) 

1.2解决方案:

1.2.1首先引入依赖

<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.12.3</version> <!-- 请根据你项目的 Jackson 版本选择合适的版本号 -->
</dependency>
1.2.2然后在RedisConfig中进行配置
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);// 设置Key序列化方式template.setKeySerializer(new StringRedisSerializer());// 设置HashKey序列化方式 template.setHashKeySerializer(new StringRedisSerializer());// 使用Jackson2JsonRedisSerializer来序列化和反序列化Redis的valueObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new JavaTimeModule());GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);// 设置Value序列化方式template.setValueSerializer(jackson2JsonRedisSerializer);// 设置HashValue序列化方式template.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}

完成配置后即可在直接将包含LocalDateTime属性的对象直接进行序列化存储在Redis中,

如redisTemplate.opsForValue().set(key,yourObject);的方式直接存储即可。

1.3 介绍下ObjectMapper

1.3.1  ObjectMapper

上面代码中配置 RedisTemplate 的序列化机制,以便能够序列化和反序列化包含 LocalDateTime 等 Java 8 时间类型的对象。我们详细分解下这几行代码的功能:

 ObjectMapper objectMapper = new ObjectMapper();

作用ObjectMapper 是 Jackson 库的核心类,用来将 Java 对象转换为 JSON 字符串,或者将 JSON 字符串解析为 Java 对象。

Jackson 是一个非常流行的 JSON 序列化和反序列化库,ObjectMapper 是它的主要接口,用于处理复杂的对象和数据结构。

1.3.2  objectMapper.registerModule(new JavaTimeModule());

作用:为 ObjectMapper 注册一个 JavaTimeModule 模块。

默认情况下,Jackson 不支持直接序列化和反序列化 Java 8 的日期时间类,如 LocalDateTime、LocalDate 等。如果直接使用 ObjectMapper 处理这些类型,会抛出异常,因为 Jackson 不知道如何正确处理这些类。

JavaTimeModule 是一个扩展模块,专门用于处理 Java 8 引入的日期和时间类型,比如 LocalDateTime、ZonedDateTime、LocalDate 等。通过注册这个模块,Jackson 就能够正确地序列化这些时间类型为 JSON,并在反序列化时也能将 JSON 转回到这些时间类型对象。

// 注册 JavaTimeModule 之后,Jackson 就可以处理 LocalDateTime 了

objectMapper.registerModule(new JavaTimeModule());

1.3.3  GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);

作用:使用上面配置好的 ObjectMapper 创建一个 GenericJackson2JsonRedisSerializer 实例,作为 Redis 的序列化工具即可。

2 问题2 从Redis取出数据转换为Java对象

2.1 引入:

       在从Redis中读取通过以上方式存储的序列化后的数据,假如你存入的是一个User 对象,User 有一个LocalDateTime类型的属性,你通过上面ObjectMapper序列化器存储到Redis中,若直接使用User user = (User) redisTemplate.opsForValue().get(key);则会出现如下错误:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.seckill.pojo.User

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.seckill.pojo.Userat com.seckill.service.impl.UserServiceImpl.getUserByCookie(UserServiceImpl.java:98)at com.seckill.service.impl.UserServiceImpl$$FastClassBySpringCGLIB$$d92357c4.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)at com.seckill.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$16ffc976.getUserByCookie(<generated>)at 

2.2 解决方案

因为包含LocalDateTime等Java8中的新类,从Redis取数据时默认会返回一个LinkedHashMap,其中keys为属性名,values为属性值。因此需要使用ObjectMapper进行类型转换。

 YourClass test = objectMapper.convertValue(redisTemplate.opsForValue().get(key),YourClass.class);

即可将获得的数据由LinkedHashMap转为对应的类别了。

3 序列化优点

1)Redis 是数据存储系统,而非 Java 对象存储系统

• Redis 支持的基础数据类型有字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等,无法直接理解和处理复杂的 Java 对象。

因此,必须将 Java 对象转化为 Redis 能够理解的格式,例如字符串或二进制字节流,这就需要序列化操作。

2)跨平台和跨语言的兼容性

• Redis 是一个与语言无关的存储系统,支持多种语言的客户端(如 Java、Python、Go 等)。序列化将 Java 对象转换为通用格式,如 JSON、XML 或二进制流,使其可以在不同平台或语言之间互操作。

• 例如,JSON 序列化可以让其他语言的客户端读取 Java 系统存入 Redis 的数据。

3)Java 对象结构复杂

• Java 对象不仅仅是基本数据类型,它可能包含嵌套的对象、集合、数组等复杂结构。这些复杂结构不能简单地转换为 Redis 可识别的字符串表示。

• 通过序列化,可以将整个对象结构转化为线性的、可传输的字节流,从而可以存储到 Redis。

4)性能优化

• 序列化后的数据通常是二进制或字符串表示,这些格式的数据可以被 Redis 高效地存储和操作,提升 Redis 的读写性能。

• 例如,使用二进制序列化可以节省存储空间,同时减少网络传输时的带宽消耗。

4 objectMapper.convertValue()

4.1 原理

ObjectMapper.convertValue() 是 Jackson 库中的方法,用于将一个对象(通常是 Map 或者其他类型的对象)转换为另一种类型。其工作原理基于 Jackson 库强大的序列化和反序列化机制,背后的基本流程是:

1. 数据的中间表示:在内部,ObjectMapper 会先将输入对象(例如 LinkedHashMap 或其他对象)转换成一种中间表示(类似 JSON 数据的内部结构),这个中间表示可以是一个 Map、数组、字符串等。

2. 类型推断和映射:convertValue() 方法会根据你传入的目标类型(例如 YourClass.class),将中间表示映射到该目标类型的字段中。这个过程类似于反序列化的过程,即 Jackson 会查看目标类中的字段和类型信息,并试图将中间表示中的数据逐一填充到目标对象的对应字段。

3. 属性映射和类型转换:convertValue() 通过 Jackson 的反射机制读取目标类的属性,并将输入对象中的数据映射到这些属性上。在这个过程中,Jackson 能自动处理各种类型转换,包括基本类型、复杂对象、集合类型,甚至像 LocalDateTime 这样的自定义对象类型(前提是 Jackson 已经配置了对这些类型的支持,例如通过 JavaTimeModule 模块)。

4.2 基本步骤

当调用 convertValue(sourceObject, TargetClass.class) 时,基本流程如下:

Step 1: 将 sourceObject 转换成内部的 JSON 树结构(例如 LinkedHashMap 等)。

Step 2: 根据目标类 TargetClass 的结构,Jackson 查找和匹配相应的属性。

Step 3: 将中间 JSON 树结构中的数据逐步填充到目标类的实例中。

Step 4: 返回填充好的目标类对象。

4.3 示例

//假设 Redis 中存储的数据反序列化为 LinkedHashMap:Map<String, Object> redisData = redisTemplate.opsForValue().get("someKey");//这个 redisData 包含了 TestPojo 对象的所有字段和对应的值。然后通过 convertValue,可以将其转换为 TestPojo 对象:YourClass yourClass = objectMapper.convertValue(redisData, YourClass.class);//Jackson 将通过字段名称和类型推断,将 redisData 中的值映射到 YourClass 的字段中。

相关文章:

Redis中储存含LocalDateTime属性对象的序列化实现

目录 1.问题1 向Redis中存入序列化对象 1.1引入 : 1.2解决方案&#xff1a; 1.2.1首先引入依赖 1.2.2然后在RedisConfig中进行配置 1.3 介绍下ObjectMapper 1.3.1 ObjectMapper 1.3.2 objectMapper.registerModule(new JavaTimeModule()); 1.3.3 GenericJackson2Js…...

蚁剑的介绍和使用

蚁剑介绍 蚁剑&#xff08;AntSword&#xff09;是一个开源的跨平台网站管理工具&#xff0c;主要用于渗透测试和安全研究。它提供了一个图形化界面&#xff0c;方便用户管理和操作被攻陷的网站。 安装教程&#xff1a; github官网&#xff1a;https://github.com/AntSwordPro…...

C++之多态的深度剖析(2)

前言 在前面内容中&#xff0c;我们对多态进行了基本的了解&#xff0c;对其中的虚函数进行着重的介绍&#xff0c;本节内容我们将进一步对多态的底层进行观察了解看看它是如何实现的。 多态如何实现 从底层的角度Func函数中ptr->BuyTicket()&#xff0c;是如何作为ptr指向P…...

一篇文章 介绍 shiro反序列化漏洞

shiro反序列化漏洞 Shiro-550反序列化漏洞&#xff08;CVE-2016-4437&#xff09; 漏洞简介 shiro-550主要是由shiro的RememberMe内容反序列化导致的命令执行漏洞&#xff0c;造成的原因是默认加密密钥是硬编码在shiro源码中&#xff0c;任何有权访问源代码的人都可以知道默认加…...

pyav保存视频

目录 imageio替代pyav imageio替代pyav import imageio import numpy as np import torch# 创建一个随机的图像张量&#xff0c;形状为 (N, C, H, W) # 这里 N 30&#xff08;帧数&#xff09;&#xff0c;C 3&#xff08;通道数&#xff09;&#xff0c;H 64&#xff08;…...

.bixi勒索病毒来袭:如何防止文件加密与数据丢失?

导言 在网络威胁剧烈的今天&#xff0c;勒索病毒已成为企业和个人面临的重大安全挑战&#xff0c;其中虫洞勒索病毒习得高强度的加密手段和急剧传播的特性引起关注。一旦感染&#xff0c;就会加密关键数据并索要赎金&#xff0c;导致数据无法访问并带来巨大的财务损失。更为严…...

MySQL安装配置教程

以下是 MySQL 在 Windows 系统下的安装配置教程: 1. 下载 MySQL 访问 MySQL 官方网站(https://dev.mysql.com/downloads/mysql/),根据您的操作系统版本(32 位或 64 位)选择合适的 MySQL 安装包。一般建议下载社区版(Community Server),它是免费且功能丰富的版本。2. …...

Pandas进行数据查看与检查

在数据分析的工作流中,数据的初步查看与检查是非常重要的步骤。通过这一步,可以快速了解数据的结构、属性以及一些关键的统计信息,确保数据符合预期,或者发现数据中的潜在问题。 借助 pandas 库中的常用方法,如 DataFrame.head()、DataFrame.tail()、DataFrame.info() 和…...

‌MySQL中‌between and的基本用法‌、范围查询

文章目录 一、between and语法二、使用示例2.1、between and数值查询2.2、between and时间范围查询2.3、not between and示例 BETWEEN AND操作符可以用于数值、日期等类型的字段&#xff0c;包括边界值。 一、between and语法 MySQL中的BETWEEN AND操作符用于在两个值之间选择…...

[ 问题解决篇 ] 解决远程桌面安全登录框的问题

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

ctfshow——web(总结持续更新)

文章目录 1、基础知识部分2、php伪协议2.1 php://input协议2.2 data://text/plain协议 3、webshell连接工具3.1 蚁剑连接一句话木马 4、各个web中间件重要文件路径4.1 Nginx 5、sqlmap使用6、php特性6.1 md5加密漏洞 7、TOP 10漏洞7.1 SQL注入 1、基础知识部分 识别base64编码…...

selinux介绍和Linux中的防火墙

selinux 1、selinux的说明 2、selinux的工作原理 3、selinux的启动、关闭与查看 防火墙 1、什么是防火墙 2、iptables &#xff08;1&#xff09;iptables介绍 参数说明 3、firewalld firewalld-cmd的参数说明...

Jenkins面试整理-如何配置 Jenkins Pipeline?

在 Jenkins 中配置 Pipeline 是将构建、测试、部署等流程自动化的重要方式。Pipeline 可以通过一个名为 Jenkinsfile 的文件配置,它允许你使用脚本定义流水线。下面是如何在 Jenkins 中配置 Pipeline 的详细步骤。 步骤 1: 准备 Jenkinsfile Jenkinsfile 是 Jenkins Pipeline …...

Java每日刷题之二分算法

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 转化 通过题目时间复杂度为O(logN),我们就可以联想到二分算法&#xff0c;但是我们前面学到的算法&#xff0c;是查找出&#xff0c;有序数组里的值&#xff0c;并不是求其中的范围&a…...

【mod分享】极品飞车9仿虚幻引擎模组,支持光追,高清纹理材质,体验一会虚幻引擎风格的极品9

各位好&#xff0c;今天小编给大家带来一款新的高清重置MOD&#xff0c;本次高清重置的游戏叫《极品飞车9最高通缉》。 《极品飞车&#xff1a;最高通缉》作为一款2005年的游戏&#xff0c;《极品飞车&#xff1a;最高通缉》的画面效果还是可以的&#xff0c;效果全开之后很不…...

【启程Golang之旅】并发编程构建简易聊天系统

欢迎来到Golang的世界&#xff01;在当今快节奏的软件开发领域&#xff0c;选择一种高效、简洁的编程语言至关重要。而在这方面&#xff0c;Golang&#xff08;又称Go&#xff09;无疑是一个备受瞩目的选择。在本文中&#xff0c;带领您探索Golang的世界&#xff0c;一步步地了…...

微信小程序的开发流程

微信小程序开发流程 1. 注册微信小程序账号 进入微信公众平台&#xff08;mp.weixin.qq.com&#xff09;&#xff0c;选择小程序的账号类型按照流程进行注册。注意每个邮箱只能注册一个账号。 2. 下载开发工具 使用账号登录微信公众平台&#xff0c;在开发->开发设置-&g…...

十分钟快速让你搞懂 Vue3 和 React 的区别

前言 Vue 3和 React是市面上目前非常受欢迎的两个前端框架。它们都采用了组件化的开发模式&#xff0c;使得开发者可以将复杂的应用拆分为多个小组件进行开发&#xff0c;从而提高了代码的可维护性和重用性。然而&#xff0c;虽然Vue 3和React都拥有各自的优点&#xff0c;但它…...

头歌——机器学习(线性回归)

文章目录 线性回归简述答案 线性回归算法答案 线性回归实践 - 波斯顿房价预测LinearRegression代码 利用sklearn构建线性回归模型示例代码如下&#xff1a; 代码 线性回归简述 简单线性回归 在生活中&#xff0c;我们常常能碰到这么一种情况&#xff0c;一个变量会跟着另一个变…...

AI驱动无人驾驶:安全与效率能否兼得?

内容概要 如今&#xff0c;人工智能正以其神奇的魔力驱动着无人驾驶的浪潮&#xff0c;带来了无数令人兴奋的可能性。这一领域的最新动态显示&#xff0c;AI技术在车辆的决策过程和实时数据分析中发挥着重要作用&#xff0c;帮助车辆更聪明地应对复杂的交通环境。通过实时监测…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...