protostuff的坑

摘要:
redisTemplate中序列化protostuff的一个特点是,在反序列化时需要指定反序列化类型Class。如果遵循常规spring数据编辑规范,则只能实现RedisSerializer接口,包括反序列化行SerializationException;无法指定类,因此我们可以改变思路。调用redisTemplate时,我们不直接放置对象,而是直接放置序列化字节[]。在反序列化时,我们获取字节[],然后通过protostuff将它们传输到相应的类。

1、Protostuff 序列化/反序列化集合等对象

定义一个包装类:

public class SerializeDeserializeWrapper<T> {

    private T data;

    public static <T> SerializeDeserializeWrapper<T> builder(T data) {
        SerializeDeserializeWrapper<T> wrapper = new SerializeDeserializeWrapper<>();
        wrapper.setData(data);
        return wrapper;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}

序列化是判断下,哪些不支持的集合,放在包装器里

@SuppressWarnings("unchecked")
    public static <T> byte[] serialize(T obj) {
        Class<T> clazz = (Class<T>) obj.getClass();
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            Object serializeObject = obj;
            Schema schema = WRAPPER_SCHEMA;
            if (!WRAPPER_SET.contains(clazz)) {
                schema = getSchema(clazz);
            } else {
                serializeObject = SerializeDeserializeWrapper.builder(obj);
            }
            return ProtostuffIOUtil.toByteArray(serializeObject, schema, buffer);
        } catch (Exception e) {
            logger.error("序列化对象异常 [" + obj + "]", e);
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            buffer.clear();
        }
    }

还有要注意的:

1、嵌套对象时,子对象不可以是内部类,不然序列化时会栈溢出。 

2、每个类需要有默认的构造方法。

2、redisTemplate中的序列化 

protostuff有一个特点就是你反序列化的时候需要指定反序列化的类型Class,而如果按常规spring-data-redis规范,只能实现RedisSerializer接口,其中反序列化接口T deserialize(byte[] bytes) throws SerializationException;无法指定Class,所以换个思路,我们在调用redisTemplate操作的时候不是直接放对象而是直接放序列化后的byte[],而反序列化的时候获取byte[]再通过protostuff转为对应的class。注意一点是enableDefaultSerializer这个属性要置为false,并且不要配置valueSerializer因为如果不设置该属性RedisTemplate初始化的时候会指定默认的序列化也就是JdkSerializationRedisSerializer来作为序列化和反序列化。

参考:https://blog.csdn.net/butioy_org/article/details/78412395

免责声明:文章转载自《protostuff的坑》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mysql 表死锁ES2020新语法【空值合并操作符 ??】和【逻辑或操作符 ||】的区别下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Newtonsoft.Json(Json.Net)学习笔记-高级使用(转)

    1.忽略某些属性     2.默认值的处理     3.空值的处理     4.支持非公共成员     5.日期处理     6.自定义序列化的字段名称   7.动态决定属性是否序列化     8.枚举值的自定义格式化问题   9.自定义类型转换   10.全局序列化设置  一.忽略某些属性   类似本问开头介绍的接口优化,实体中有些属性不需要序列...

Django之缓存、信号和图片验证码、ORM性能

一、 缓存 1、 介绍 缓存通俗来说:就是把数据先保存在某个地方,下次再读取的时候不用再去原位置读取,让访问速度更快。 缓存机制图解 2、Django中提供了6种缓存方式   1. 开发调试   2. 内存   3. 文件   4. 数据库   5. Memcache缓存(python-memcached模块)   6. Memcache缓存(pyl...

深入浅出 RPC

《深入篇》我们主要围绕 RPC 的功能目标和实现考量去展开,一个基本的 RPC 框架应该提供什么功能,满足什么要求以及如何去实现它? RPC 功能目标 RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用,在前文...

监控Spark应用方法简介

监控Spark应用有很多种方法。Web接口每一个SparkContext启动一个web UI用来展示应用相关的一些非常有用的信息,默认在4040端口。这些信息包括:任务和调度状态的列表RDD大小和内存使用的统计信息正在运行的executor的信息环境信息你可以在浏览器中打开http://<driver-node>:4040网址来访问这些信息。如...

ehcache历史变迁及常用API的使用(转)

  ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时ehcache作为开放源代码项目,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate, Spring,Cocoon等其他开源系统...

Redis系统学习之自定义RedisTemplate

自定义RedisTemplate 序列化源码分析 在JAVA程序中看到中文是没有问题的,但是在Redis客户端工具,也就是命令行中看见是编码的 继续分析源码 查看RedisTemplate.class 在RedisAutoConfiguration.class中点击 在上面可以看到序列化支持的 往下稍微滑动一些可以看到,默认采用的是JDK的序列化,...