首页 > 其他分享 >序列化和反序列化

序列化和反序列化

时间:2024-11-11 21:47:09浏览次数:3  
标签:对象 子类 ctx JSON 枚举 序列化

目录

一、是什么

序列化(Serialization)

反序列化(Deserialization)

二、使用场景

三、框架

四、问题

五、Jackson 枚举反序列化器

一、是什么

序列化(Serialization)

是将数据结构或对象转换成一种可存储或可传输格式的过程。在序列化后,数据可以被写入文件、发送到网络或存储在数据库中,以便在需要时可以再次还原成原始的数据结构或对象。序列化的过程通常涉及将数据转换成字节流或类似的格式,使其能够在不同平台和编程语言之间进行传输和交换。

反序列化(Deserialization)

是序列化的逆过程,即将序列化后的数据重新还原成原始的数据结构或对象。反序列化是从文件、网络数据或数据库中读取序列化的数据,并将其转换回原始形式,以便在程序中进行使用和操作。

二、使用场景

  • 数据存储:将程序中的数据保存到文件或数据库中,以便在以后重新加载和使用。
  • 网络通信:在网络上传输数据时,需要将数据序列化为字节流,以便在接收端进行反序列化。
  • 分布式系统:在分布式系统中,不同计算节点之间需要通过序列化和反序列化来交换数据。
  • 进程间通信:不同进程之间通信时,数据需要在序列化和反序列化之间进行转换。
  • 常见的序列化格式包括 JSON(JavaScript Object Notation)、XML(eXtensible Markup Language)、Protocol Buffers、MessagePack等。每种格式有其优势和适用场景,选择合适的序列化格式取决于具体的应用需求。

三、框架

XML 序列化框架介绍
XML 序列化的好处在于可读性好,方便阅读和调试。但是序列化以后的字节码文件比较大, 而且效率不高,适用于对性能不高。

JSON 序列化框架
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相对于XML来说,JSON 的字节流更小,而且可读性也非常好。现在JSON数据格式在企业运用是最普遍的 JSON序列化常用的开源工具有很多,如:

  • Jackson 
  • 阿里开源的FastJson 

四、问题

父类实现了序列化,子类需不需要实现序列化?反过来子类需要实现序列化,父类要不要实现序列化?

  • 父类实现了序列化,则子类自动实现了序列化,即子类不需要显式实现Serializable接口,子类构造时会递归调用父类构造。
  • 当父类没有实现序列化,而子类需要实现时,子类需要显式实现Serializable接口,并且父类中需要有无参的构造函数。

序列化保存的是对象还是方法?

  •  序列化时,只对对象的状态进行保存,而不管对象的方法

        但是并非所有的对象都可以序列化,比如:

  • 安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
  •  资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分配,而且,也是没有必要这样实现。

注意

  • 类中的实例变量引用了其他对象,那么在对该类进行序列化时,引用的对象也会被序列化(需要这个引用的对象也实现Serializable接口,否则会出java.io.NotSerializableException)
  • 静态成员变量属于类不属于对象,所以不参与序列化过程。
  • transient关键字标记的成员变量不参与序列化过程。

五、Jackson 枚举反序列化器


/*
@Slf4j:这是 Lombok 提供的注解,用于自动生成一个名为 log 的日志记录器。你可以通过这个记录器来打印日志信息。
@Setter:Lombok 提供的另一个注解,自动为类中的属性生成 setter 方法。
@JsonComponent:这是 Jackson 提供的注解,表明该类是一个 JSON 组件,可以被 Jackson 管理。
*/
@Slf4j
@Setter
@JsonComponent
public class JacksonEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
    private Class<?> clazz;//用于存储待反序列化的枚举的 Class 对象。

    /**
     * 反序列化操作
     *
     * @param   jsonParser
     *          json 解析器
     *
     * @param   ctx
     *          反序列化上下文
     *
     * @return  反序列化后的枚举值
     * @throws  IOException  反序列化异常
     */

    @Override
   // 定义一个枚举类型,需要使用 enum 关键字,后面跟着枚举类型的名称,
    public  Enum<?>deserialize(JsonParser jsonParser, DeserializationContext ctx)throws IOException {
        Class<?>enumType = clazz;
        if(Objects.isNull(enumType)||enumType.isEnum()){
            return null;
        }
        //读取 JSON 中的文本值 text。
        String text = jsonParser.getText();
        //遍历枚举常量,使用 StringToEnumConverterFactory 中的方法转换字符串值,判断是否与 text 相匹配。如果找到匹配的枚举值,则返回该枚举对象。
        Method[] method = StringToEnumConverterFactory.getMethod(clazz);
        Enum<?>[] enumConstants = (Enum<?>[]) enumType.getEnumConstants();

        for (Enum<?> e : enumConstants) {
            try{
                if(Objects.equals(method.invoke(e).toString(),text)){
                    return e;
                }
            }catch (IllegalAccessException | InvocationTargetException ex){
                log.error("获取枚举值错误",ex);
            }
        }
        return null;

    }
    /**
     * 为不同的枚举获取合适的解析器
     *
     * @param   ctx
     *          反序列化上下文
     *
     * @param   property
     *          property
     */
    @Override
    public  JsonDeserializer<Enum<?>> createContextual(DeserializationContext ctx, BeanProperty property){
     //从上下文中获取要反序列化的枚举的原始类 rawCls。
        Class<?>rawCls = ctx.getContextualType().getRawClass();
        // 创建一个新的 JacksonEnumDeserializer 实例,并设置其 clazz 属性为 rawCls。
        JacksonEnumDeserializer converter = new JacksonEnumDeserializer();
        converter.setClazz(rawCls);
        return converter;
    }

}

                 

标签:对象,子类,ctx,JSON,枚举,序列化
From: https://blog.csdn.net/liiilbb/article/details/143692183

相关文章

  • DAY109代码审计-PHP模型开发篇&动态调试&反序列化&变量覆盖&TP框架&原生POP链
    知识点1、PHP审计-动态调试-变量覆盖2、PHP审计-动态调试-原生反序列化3、PHP审计-动态调试-框架反序列化PHP常见漏洞关键字SQL注入:selectinsertupdate deletemysql_querymysqli等文件上传:$_FILES,type="file",上传,move_uploaded_file()等XSS跨站:printprint_r......
  • Java中序列化与反序列化
    序列化(Serialization)和反序列化(Deserialization)是计算机科学中用于数据存储和传输的两种基本操作。序列化:序列化是将对象的状态信息转换为可以存储或传输的形式的过程。简单来说,就是将对象转换为字节序列(比如JSON、XML等格式)。目的:使得对象可以在网络上进行传输,或者存储到文......
  • 读数据工程之道:设计和构建健壮的数据系统32序列化和云网络
    1. 序列化1.1. 仅仅通过从CSV转换到Parquet序列化,任务性能就提高了上百倍1.2. 基于行的序列化1.2.1. 基于行的序列化是按行来组织数据1.2.2. 对于那些半结构化的数据(支持嵌套和模式变化的数据对象)​,基于行的序列化需要将每个对象作为一个单元来存储1.2.3. CSV格......
  • ue4资产序列化从入门到精通: 第一章 初识序列化
    一、写作目的:(全文字数4926,阅读大约需25min)首先,我有一个相关的需求要做,然后在拜读了网络上各大UE4序列化解析的文章后,发现大都讲的很模糊,对新入序列化大门的小白非常不友好。有的直接贴上一大段代码(好似直接糊脸上的不解释连招),也有的讲着讲着嘎然而止,也有的总是讲一些空洞的理......
  • Java中的序列化和反序列化是什么
    序列化是将对象转换为字节流的过程,这样对象可以通过网络传输、持久化存储或者缓存。Java提供了java.io.Serializable接口来支持序列化,只要类实现这个接口,就可以将该类的对象进行序列化。反序列化是将字节流重新转换为对象的过程,即从存储中读取数据并重新创建对象。其他应用......
  • CTF web新手解题——php反序列化 【ez_ez_unserialize】
    感受最大的就是:作为web新手,应速通并逐渐掌握php语言收获:从此题提高了我对代码的理解力【ez_ez_unserialize】NSSCTF{1ba5d701-3b8a-4a83-965d-7e912ef6f43b}分析存在__wakeup()魔术方法unserialize()会检查是否存在一个__wakeup()方法。如果存在,则会先调用__wakeup......
  • 什么是java序列化?什么情况下需要序列化?
      序列化的定义Java序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。序列化是一种用于处理对象流的机制,它将对象的内容转换成一种可以在网络之间传输的形式。反序列化则是将这种形式的对象恢复成原来的对象。实现方式序列化是通过实现​​Seri......
  • 什么是java序列化?什么情况下需要序列化?
      序列化的定义Java序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。序列化是一种用于处理对象流的机制,它将对象的内容转换成一种可以在网络之间传输的形式。反序列化则是将这种形式的对象恢复成原来的对象。实现方式序列化是通过实现​​Seri......
  • java 对象序列化
    文章目录对象状态保存与序列化序列化的基本原理实现对象序列化的步骤示例代码代码说明序列化中的关键点序列化的应用场景自定义序列化方法多次序列化序列化多个对象:多次序列化同一个对象序列化相同内容的对象同一对象序列化后的追踪修改一,reset()方法二,储存在不同的文件内......
  • 序列化与反序列化+SQL函数
    序列化其实就是一种对象,平时写的自定义类,内存上就是对象,可以保存到硬盘上,就是序列化,反过来就是反序列化序列化:对象转换为字节反序列化:字节重构为对象实际上也是输入输出流,只不过加了Object即ObjectOutputStreamObjectOutputStream类构造方法:OutputStream里面传的是FileO......