首页 > 编程语言 >java类序列化和反序列化

java类序列化和反序列化

时间:2023-05-06 16:13:26浏览次数:50  
标签:java 对象 接口 json 序列化 Serializable

参考:https://zhuanlan.zhihu.com/p/144535172?utm_id=0
https://blog.csdn.net/qq_42617455/article/details/109622390

1、问题解答

(1)序列化和反序列化都需要哪些操作
对象要实现java.io.Serializable接口
增加序列化 ID(private static final long serialVersionUID)
转化成便于传输的格式
(2)在项目开发中我们使用的是比较流行的前后端分离,我向前端传输数据的时候也没有进行这些操作啊?
下面就是要说的在进行项目开发过程中常用的序列化格式json字符串。看过javaSE源码的都知道字符串是已经实现了Serializable接口的,所以字符串这种数据类型很方便用于传输,因为序列化和反序列的那些操作jdk已经给咱们封装好了,不需要咱们在考虑只需要专注于业务就ok了。
(3)json
什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法。
(4)springboot的json序列化

  • Springboot目前最火的框架,在进行对象传输的时候springboot是怎么处理的,springboot项目中使用@ResponseBody或者@RestController自动的将对象转化成json字符串传递给前端(原理是默认使用jackson包进行的处理)
    我们的类并没有实现Serializable接口,实际上这是Spring框架帮我们做了一些事情,Spring并不是直接把User对象进行网络传输,而是先把User对象转换成json格式的字符串,然后再进行传输的,而String类实现了Serializable接口并且显示指定了serialVersionUID 。

版权声明:本文为CSDN博主「Mounsey」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42617455/article/details/109622390

  • 前端向后端发送json字符串。前端向后端传递json时需要转化成json字符串,后端通过@RequestBody可以把这个json字符串映射成java对象或者hashMap

  • 这些注解之所以可以进行Json与JavaBean之间的相互转换,就是因为HttpMessageConverter发挥着作用。
    org.springframework.http.converter.HttpMessageConverter 是一个策略接口,是Http request请求和response响应的转换器,该接口只有五个方法,它的canRead()方法返回true,然后它的read()方法会从请求中读出请求参数,绑定到readString()方法的string变量中。
    当SpringMVC执行readString方法后,由于返回值标识了@ResponseBody,SpringMVC将使用StringHttpMessageConverter的write()方法,将结果作为String值写入响应报文,当然,此时canWrite()方法返回true。

public interface HttpMessageConverter<T> {
 
	//判断当前转换器是否可以解析前端传来的数据
	boolean canRead(Class<?> clazz, MediaType mediaType);
	
	//判断当前转换器是否可以将后端数据解析为前端需要的格式
	boolean canWrite(Class<?> clazz, MediaType mediaType);
 
	//获取当前转换器可以解析的数据类型
	List<MediaType> getSupportedMediaTypes();
 
	//读取前端传来的数据
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;
 
	//将后台数据转换,返回给前端
	void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;
 }

流程如下:
image
前端发来请求后,先调用HttpInputMessage从输入流中获取Json字符串,然后在HttpMessageConverter中把Json转换为接口需要的形参类型。在HttpMessageConverter内部流程图如下:
image

2、序列化和反序列化

(1)介绍
java序列化是指把java对象转换为字节序列化的过程,而反序列化是指把字节序列恢复为java对象的过程。
(2)实现
被序列化的对象需要实现java.io.Serializable接口,该接口只是一个标记接口,不用实现任何方法

JDK提供java对象的序列化方式实现对象序列化传输,主要通过输出流java.io.ObjectOutputStream和对象输入流java.io.ObjectInputStream实现

java.io.ObjectOutputStream:表示对象输出流 , 它的writeObject(Object obj)方法可以对参 数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

java.io.ObjectInputStream:表示对象输入流 ,它的readObject()方法源输入流中读取字节序 列,再把它们反序列化成为一个对象,并将其返回。

serialVersionUID作用:虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化id是否一致。注意:序列化类新增属性时,不要修改serialVersionUID,避免反序列化失败,如果完全不兼容升级,避免发序列化混乱,那么请修改serialVersionUID值。
例如:开始的uid是1,后改成2则会报错

package com.redis.demo.dto;

import com.redis.demo.aop.Dict;
import lombok.Data;

import java.io.Serializable;

/**
 * @Description :
 * @Date : 2023/5/5
 * @Author :
 */
@Data
public class TestDto implements Serializable {
    private String a;

    private String name;

    private static final long serialVersionUID =1L;
}

序列化

  public static void main(String[] args) throws Exception {
        /**
         * 将序列化保存到object.out文件
         */
        FileOutputStream fos = new FileOutputStream("object.out");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        TestDto testDto = new TestDto();
        testDto.setA("a");
        testDto.setName("name");
        oos.writeObject(testDto);
        System.out.println(oos);
        oos.flush();
        oos.close();
    }

反序列化,如果将TestDto的uid改成其他,则反序列化会报错

   public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("object.out");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object o = ois.readObject();
        TestDto t = (TestDto) o;

        System.out.println(t);
    }

image

标签:java,对象,接口,json,序列化,Serializable
From: https://www.cnblogs.com/cgy1995/p/17377665.html

相关文章

  • java内存监控工具及命令
    关键字:内存监控工具及命令一篇非常好的内存监控知识,分享给爱学习的亲们.....jinfo:可以输出并修改运行时的java进程的opts。jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。jstat:一个极强的监视VM......
  • 在java 中, 如果三目运算符 是个函数,函数是一定会被执行吗
    在Java中,如果三目运算符中的取值是一个函数,函数不一定会被执行。这取决于三目运算符的条件表达式的结果。如果三目运算符的条件表达式的结果为true,那么执行函数并返回其结果;如果条件表达式的结果为false,那么不执行函数,直接返回另一个值。下面是一个示例代码:intx=5;int......
  • django内置序列化组件(drf前身)
    目录一、django内置序列化组件(drf前身)一、django内置序列化组件(drf前身)一、django内置序列化组件(drf前身)这里的内置序列化组件,其实就是实现将后端数据,存放到字典中或是存放到列表中有序输出。这里是我们用JsonResponse模块自己实现的代码'''前后端分离的项目视图函数......
  • 27基于java的学生在线考试系统
    一、项目简介随着互联网迅速发展,人们的生活已经越来越离不开互联网,人们足不出户就可以工作、学习等。对于在校学生,通过网络教育不仅可以随时进行网络学习,也可以根据学习的情况自我检测,有利于学生高效、快捷地掌握所学的知识。本系统预设计的基于网络的学生自测系统将实现多种用......
  • Java获取pdd详情api接口、商品详情、商品描述、宝贝链接获取展示示例
    ​拼多多商品详情就是对拼多多商城中的宝贝的描述了,消费者们在进入到宝贝的详情页面后,可以通过这些描述去了解该款宝贝。其实这样也可以大大的增加商品的转化率。那么它的作用有什么呢?1.突出商品卖点:把商品的特色和突出点写表现出来,很更好的吸引到顾客,让顾客有点击和购买的欲......
  • java中static方法不能被重写但是能重定义
    1、static方法不能被重写示例1classAnimal{publicstaticvoidwalk(){System.out.println("Animal的行走方法");}}classDogextendsAnimal{publicvoidwalk(){System.out.println("Dog的行走模式");}publicstaticv......
  • ubuntu x64 安装java 7
    安装步骤来自社区:https://help.ubuntu.com/community/Java中的http://askubuntu.com/questions/56104/how-can-i-install-sun-oracles-proprietary-java-6-7-jre-or-jdk因为是初次安装.所以,提示会不一样.简单的操作完成后.就可以使用了.安装jdk也一样的道理.操作完全可都一样.htt......
  • AndroidStudio插件GsonFormat快速实现JavaBean
    安装方法一:1.AndroidstudioFile->Settings..->Plugins–>Browserepositores..搜索GsonFormat2.安装插件,重启androidstudio方法二:1.下载GsonFormat.jar;2.AndroidstudioFile->Settings..->Plugins–>installpluginfromdisk..导入下载GsonFormat.jar3.重启android......
  • Java 内存分配全面浅析
    本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。本文从认知过程角度出发,将带给读者一个系统的介绍。进入正题前首先要知道的是Java程序运行在JVM(JavaVirtualMachine,Java虚拟机)上,可以把JVM理解成Java程序和操作系......
  • 深入浅出RxJava(一:基础篇)
    RxJava正在Android开发者中变的越来越流行。唯一的问题就是上手不容易,尤其是大部分人之前都是使用命令式编程语言。但是一旦你弄明白了,你就会发现RxJava真是太棒了。这里仅仅是帮助你了解RxJava,整个系列共有四篇文章,希望你看完这四篇文章之后能够了解RxJava背后的思想,并且喜欢上......