redission自定义hessian序列化
一。技术改造背景
由于之前的比较陈旧的技术,后面发起了技术改造,redis整体改后使用redisson框架。
二。问题
改造完成后,使用方反馈 缓存获取异常 异常信息如下
Caused by: java.io.CharConversionException: Unexpected EOF in the middle of a 4-byte UTF-32 char: got 1, needed 4, at char #1, byte #5)
at com.fasterxml.jackson.core.io.UTF32Reader.reportUnexpectedEOF(UTF32Reader.java:187)
at com.fasterxml.jackson.core.io.UTF32Reader.loadMore(UTF32Reader.java:248)
at com.fasterxml.jackson.core.io.UTF32Reader.read(UTF32Reader.java:126)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._loadMore(ReaderBasedJsonParser.java:276)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken2(ReaderBasedJsonParser.java:2727)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2707)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1986)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:802)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4761)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4667)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3666)
at org.redisson.codec.JsonJacksonCodec$2.decode(JsonJacksonCodec.java:99)
at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:393)
at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:205)
at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:144)
at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:120)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:519)
at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
三。问题定位
从日志上来看 解密失败了,回头看未改造的redis 存储的序列化方式是 hessian 而改造后的 redis存储的序列化方式是JsonJacksonCodec 导致反序列化报错
四。问题解决
具体问题定位到了后 解决办法就已经有了。
- 修改redisson的序列化方式 保持和旧的序列化方式相同
- 做缓存迁移或者缓存全量失效(理论来讲不太现实)
那这个很明显,选择修改redisson的序列化方式 保持和旧的序列化方式相同。
redison目前支持的 序列化方式
Codec class name | Description |
---|---|
org.redisson.codec.Kryo5Codec | Kryo 5 binary codec (Android compatible) Default codec |
org.redisson.codec.KryoCodec | Kryo 4 binary codec |
org.redisson.codec.JsonJacksonCodec | Jackson JSON codec. Stores type information in @class field (Android compatible) |
org.redisson.codec.TypedJsonJacksonCodec | Jackson JSON codec which doesn’t store type id (@class field) during encoding and doesn’t require it for decoding |
org.redisson.codec.AvroJacksonCodec | Avro binary json codec |
org.redisson.codec.SmileJacksonCodec | Smile binary json codec |
org.redisson.codec.CborJacksonCodec | CBOR binary json codec |
org.redisson.codec.MsgPackJacksonCodec | MsgPack binary json codec |
org.redisson.codec.IonJacksonCodec | Amazon Ion codec |
org.redisson.codec.SerializationCodec | JDK Serialization binary codec (Android compatible) |
org.redisson.codec.LZ4Codec | LZ4 compression codec. Uses Kryo5Codec for serialization by default |
org.redisson.codec.SnappyCodecV2 | Snappy compression codec based on snappy-java project. Uses Kryo5Codec for serialization by default |
org.redisson.codec.MarshallingCodec | JBoss Marshalling binary codec Deprecated! |
org.redisson.client.codec.StringCodec | String codec |
org.redisson.client.codec.LongCodec | Long codec |
org.redisson.client.codec.ByteArrayCodec | Byte array codec |
org.redisson.codec.CompositeCodec | Allows to mix different codecs as one |
很意外并没有 我们需要的hessian的序列化 只能手写! redisson 默认的序列化方式为Kryo5Codec
首先引入依赖
<dependency><groupId>com.caucho</groupId><artifactId>hessian</artifactId><version>4.0.66</version>
</dependency>
其次继承 BaseCodec 实现我们的 HessianCoder 即可 完整的实现如下
import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.redisson.client.codec.BaseCodec;
import org.redisson.client.handler.State;
import org.redisson.client.protocol.Decoder;
import org.redisson.client.protocol.Encoder;import java.io.IOException;/*** 自定义实现 Hessian 序列化 兼容原有的序列化方式** @author leon* @date 2023-08-10 15:14:03*/
@Slf4j
public class HessianCoder extends BaseCodec {private final Encoder encoder = new Encoder() {@Overridepublic ByteBuf encode(Object in) throws IOException {try (ByteBufOutputStream os = new ByteBufOutputStream(ByteBufAllocator.DEFAULT.buffer())) {HessianOutput ho = new HessianOutput(os);ho.writeObject(in);return os.buffer();} catch (Exception e) {log.error("Hessian序列化异常: {}", e.getMessage(), e);throw new IOException(e);}}};private final Decoder<Object> decoder = new Decoder<Object>() {@Overridepublic Object decode(ByteBuf buf, State state) throws IOException {try (ByteBufInputStream inputStream = new ByteBufInputStream(buf)) {HessianInput hi = new HessianInput(inputStream);return hi.readObject();} catch (Exception e) {log.error("Hessian反序列化异常: {}", e.getMessage(), e);throw new IOException(e);}}};@Overridepublic Decoder<Object> getValueDecoder() {return decoder;}@Overridepublic Encoder getValueEncoder() {return encoder;}
}
最后修改我们的redisson配置 将序列化方式替换为HessianCoder 即可
在进行测试获取缓存 也没报错了。
参考官方文档:https://github.com/redisson/redisson/wiki/4.-data-serialization
相关文章:
redission自定义hessian序列化
一。技术改造背景 由于之前的比较陈旧的技术,后面发起了技术改造,redis整体改后使用redisson框架。 二。问题 改造完成后,使用方反馈 缓存获取异常 异常信息如下 Caused by: java.io.CharConversionException: Unexpected EOF in the mid…...

P8642 [蓝桥杯 2016 国 AC] 路径之谜
[蓝桥杯 2016 国 AC] 路径之谜 题目描述 小明冒充 X X X 星球的骑士,进入了一个奇怪的城堡。 城堡里边什么都没有,只有方形石头铺成的地面。 假设城堡地面是 n n n\times n nn 个方格。如图所示。 按习俗,骑士要从西北角走到东南角。 …...

oracle sql developer批量删除某个用户
随着navicate收费,还得破解,pl/sql developer配置麻烦,最近使用oracle sql developer来试试oracle的操作如何; 用着还行,没有卡顿现象, 最近要oracle sql developer批量删除某个用户下所有的表࿰…...

k8s 滚动更新控制(一)
在传统的应用升级时,通常采用的方式是先停止服务,然后升级部署,最后将新应用启动。这个过程面临一个问题,就是在某段时间内,服务是不可用的,对于用户来说是非常不友好的。而kubernetes滚动更新,…...

Java智慧工地APP源码带AI识别
智慧工地为建筑全生命周期赋能,用创新的可视化与智能化方法,降低成本,创造价值。 一、智慧工地APP概述 智慧工地”立足于互联网,采用云计算,大数据和物联网等技术手段,针对当前建筑行业的特点,…...

ME3116电源小板
最近设计一款PCB的时候使用微盟的dc dc电源ic踩了一个坑。 在使用me3116作为24v到5v的降压ic作为esp32系统前级的降压电路时,再没有铂电阻采样负载的情景下工作正常,带上负载后,ic工作不正常,过一段时间,后级电路会烧…...

摸准天气“小心思”,躲避恶劣天气“偷袭”
打开天气预报一看,天气真的很“善变”,既是高温又暴雨,偶尔还有台风路过,“蒸”的让人太太太难受了。看着天气在放晴和即将下雨之间“徘徊”,总是纠结带不带雨伞,让我的每次出门都成了一场冒险之旅。 持…...

Golang 局部变量、全局变量 声明
文章目录 一、局部变量二、全局变量 一、局部变量 四种声明方式 多变量声明: package mainimport "fmt"//局部变量声明 func main() {//方法一: 声明一个变量和数据类型,不初始化值;默认值为0;var lvA intfmt.Printl…...

软考高级之系统架构师之数据通信与计算机网络
概念 OSPF 在划分区域之后,OSPF网络中的非主干区域中的路由器对于到外部网络的路由,一定要通过ABR(区域边界路由器)来转发,既然如此,对于区域内的路由器来说,就没有必要知道通往外部网络的详细路由,只要由…...

牛客网华为OD前端岗位,面试题库练习记录01
题目一 质数因子 功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 ) JavaScript Node ACM模式 const rl require("readline").createInterface({ i…...

Python web实战之Django 的缓存机制详解
关键词:Python、Web 开发、Django、缓存 1. 缓存是什么?为什么需要缓存? 在 Web 开发中,缓存是一种用于存储数据的临时存储区域。它可以提高应用程序的性能和响应速度,减轻服务器的负载。 当用户访问网页时ÿ…...

chatserver服务器开发笔记
chatserver服务器开发笔记 1 chatserver2 开发环境3 编译 1 chatserver 集群聊天服务器和客户端代码,基于muduo、redis、mysql实现。 学习于https://fixbug.ke.qq.com/ 本人已经挂github:https://github.com/ZixinChen-S/chatserver/tree/main 需要该项…...
DP——动态规划
DP——动态规划 动态规划算法动态规划的一般步骤特殊DP——背包0-1背包问题完全背包问题 总结 动态规划算法 当涉及到解决具有重叠子问题的优化问题时,动态规划是一种常用的算法技术。它通过将问题分解为一系列重叠子问题,并使用递归或迭代的方式来解决…...

【Windows 11】安装 Android子系统 和 Linux子系统
本文使用电脑系统: 文章目录 一、安卓子系统1.1 安装 WSA1.2 使用 二、Linux子系统2.1 安装 WSL 以及WSL 相关概念2.2 安装一个Linux发行版2.21 从Microsoft Store 安装2.22 用命令安装 2.23 拓展 三、拓展3.1 存储位置3.2 虚拟化技术3.3 Windows 虚拟内存3.3 wsl …...

秒杀库存解决方案
电商系统中秒杀是一种常见的业务场景需求,其中核心设计之一就是如何扣减库存。本篇主要分享一些常见库存扣减技术方案,库存扣减设计选择并非一味追求性能更佳,更多的应该考虑根据实际情况来进行架构取舍。在商品购买的过程中,库存…...

[免费在线] 将 PDF 转换为 Excel 或 Excel 转换为 PDF | 5 工具
有了免费的在线 PDF 转换器,您可以轻松免费在线将 PDF 转换为 Excel 或 Excel 转换为 PDF。这篇文章为您筛选了 5 个最常用的工具。要从存储介质恢复错误删除或丢失的 PDF 文档、Excel 电子表格、Word 文件或任何其他文件,您可以使用免费的数据恢复程序 …...
PLC求解弹簧质量模型微分方程数值解(RK4梯形图程序)
微分方程的数值求解,属于数学分析类课程涉及的内容。大家可以参看相关书籍对Runge-Kutta法的介绍,弹簧质量阻尼模型详细的微分方程介绍可以查看下面文章,链接如下: 弹簧质量阻尼系统前馈PID位置控制(PLC闭环仿真SCL+ST代码)_RXXW_Dor的博客-CSDN博客带前馈控制的博途PID程…...

CSDN编程题-每日一练(2023-08-14)
CSDN编程题-每日一练(2023-08-14) 一、题目名称:小股炒股二、题目名称:王子闯闸门三、题目名称:圆小艺 一、题目名称:小股炒股 时间限制:1000ms内存限制:256M 题目描述: …...
【SA8295P 源码分析】69 - Android 侧添加支持 busybox telnetd 服务
【SA8295P 源码分析】69 - Android 侧添加支持 busybox telnetd 服务 一、下载 busybox-1.36.1.tar.bz2 源码包二、编译 busybox 源码三、将编译后的 busybox 打包编入Android 镜像中系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》 本文链接:《【SA8295P 源码…...

OpenCV图像处理——模版匹配和霍夫变换
目录 模版匹配原理实现 霍夫变换霍夫线检测 模版匹配 原理 实现 rescv.matchTemplate(img,template,method)import numpy as np import cv2 as cv import matplotlib.pyplot as pltimgcv.imread(./汪学长的随堂资料/6/模板匹配/lena.jpg) templatecv.imread(./汪学长的随堂资…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...