Java中的序列化方法探索

.为什么要序列化

对象不序列化,能直接存储吗?
在 Java 中,序列化是将对象的状态信息转换为可以存储或传输的形式(例如,转换为字节流)的过程。在对象数据需要在网络上传输或需要在磁盘上持久化存储时,序列化是必不可少的
对象在没有序列化的情况下不能直接存储在像文件系统或数据库这样的持久化存储中。序列化是将对象的状态转换为一种可以存储或传输的格式的过程。
没有序列化,对象是一个内存中的数据结构,不能直接存储到硬盘或通过网络传输。如果要持久化存储或在网络间传输一个对象,您需要先将其序列化为如二进制、JSON、XML 等格式。
这些格式可以被写入文件系统、数据库或通过网络发送,并在需要时反序列化回原始对象。

java中的序列化几种形式

Java 原生序列化:通过实现 java.io.Serializable 接口。对象被转换成二进制流以便于存储或传输。
JSON 序列化:使用库如 Jackson 或 Gson,将对象转换为 JSON 格式的字符串。
XML 序列化:使用如 JAXB (Java Architecture for XML Binding) 等库将对象转换为 XML 格式。
Google Protocol Buffers:一种语言和平台无关的高效二进制序列化库。
Apache Avro:支持丰富的数据结构的数据序列化系统。
Kryo:一个快速高效的 Java 二进制序列化和反序列化库。

以下以Serializable 和 JSON做分析

java 原生的序列化机制Serializable

在 Java 中,可以通过 原生的序列化机制。实现 java.io.Serializable 接口来启用对象的序列化。这个接口是一个标记接口,它不包含任何方法,仅标记类的对象可以被序列化。
版本兼容性:如果序列化的对象在不同版本之间发生变化,可能会遇到兼容性问题。为此,可以使用 serialVersionUID 来管理版本。
transient 关键字:如果您的类中有一些不需要序列化的字段(无论是 String 类型还是其他类型),可以使用 transient 关键字标记这些字段。
private int myInt; // 基本类型 int
在 Java 中,基本数据类型(如 int、double、boolean 等)本身并不实现 Serializable 接口,因为它们不是对象。但是,当基本数据类型被用作类的字段时,在该类实现了 Serializable 接口的情况下,这些基本数据类型的字段会自动包含在序列化过程中。
这意味着,如果您创建了一个实现了 Serializable 接口的类,并且这个类包含基本数据类型的字段,那么当您序列化这个类的对象时,这些基本数据类型的字段也会被序列
通常Serializable 序列化会有乱码
序列化过程生成的二进制数据不仅包含字符串的内容,还包含了 Java 对象序列化的附加信息,如类信息、序列化版本 ID 等。
这部分数据在文本编辑器中通常显示为乱码,因为它们包含非文本字符
Serializable序列化的的二进制,查看可以用二进制编辑器查看,不过可是不可识别的字符
(Notepad++ 安装插件 HEX-Editor 8.5.3Notepad++ 下载0.9.12 HEX-Editor)
在这里插入图片描述

测试 HashMap序列化与反序列化

package com.example.demo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;

public class SerializeExample {
public static void main(String[] args) {
String str = “Hello, World!”; // 字符串对象
try {
// 创建一个指向文件的输出流
FileOutputStream fileOut = new FileOutputStream(“D:\file.bin”);
// 创建一个对象输出流,并将其包装在 fileOut 流中
ObjectOutputStream out = new ObjectOutputStream(fileOut);
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(“key”,“111”);
// 序列化字符串对象
out.writeObject(hashMap);

        // 关闭所有流out.close();fileOut.close();System.out.println("Serialized data is saved in string.ser");} catch (IOException i) {i.printStackTrace();}
}

}

package com.example.demo;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;

public class DeserializeExample {
public static void main(String[] args) {
HashMap<String,String> str = new HashMap();
try {
// 创建一个指向文件的输入流
FileInputStream fileIn = new FileInputStream(“D:\file.bin”);
// 创建一个对象输入流,并将其包装在 fileIn 流中
ObjectInputStream in = new ObjectInputStream(fileIn);

        // 反序列化字符串对象  反序列化时使用 ObjectInputStream 读取序列化的对象数据,会返回一个 Object 类型的实例。如果您知道该对象的具体类型,通常需要进行显式的类型转换(强转)以恢复到其原始类型。str = (HashMap<String, String>) in.readObject();str.forEach((k,v)->{System.out.println(k+"        "+v);});// 关闭所有流in.close();fileIn.close();System.out.println("Deserialized String: " + str);} catch (IOException i) {i.printStackTrace();return;} catch (ClassNotFoundException c) {System.out.println("String class not found");c.printStackTrace();return;}
}

}

二:JSON序列化

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式(一种格式)。JSON 使用文本格式来表示对象,使其网络上进行数据传输,被绝大多数编程语言解析。
普通文本对象打印为:对象信息,别人无法识别
package com.example.demo;

import com.alibaba.fastjson.JSON;
import java.io.FileWriter;
import java.io.IOException;

public class JsonToFileExample {

public static void main(String[] args) {// 创建要序列化的对象MyObject obj = new MyObject();obj.setName("Example Name");obj.setValue(123);// 使用 Fastjson 将对象转换为 JSON 字符串

// String jsonString = JSON.toJSONString(obj);

    // 将 JSON 字符串保存到文件try (FileWriter file = new FileWriter("D:\\object.txt")) {file.write(obj.toString());file.flush();} catch (IOException e) {e.printStackTrace();}
}static class MyObject {private String name;private int value;// getters 和 setterspublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}
}

}
在这里插入图片描述
如果转成json则可以打印为:
public class JsonToFileExample {

public static void main(String[] args) {// 创建要序列化的对象MyObject obj = new MyObject();obj.setName("Example Name");obj.setValue(123);// 使用 Fastjson 将对象转换为 JSON 字符串String jsonString = JSON.toJSONString(obj);// 将 JSON 字符串保存到文件try (FileWriter file = new FileWriter("D:\\object.txt")) {file.write(jsonString);file.flush();} catch (IOException e) {e.printStackTrace();}
}static class MyObject {private String name;private int value;// getters 和 setterspublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}
}

在这里插入图片描述

在 Spring Boot 项目中,使用 Feign 进行远程调用时,对象的传输通常不依赖于 Java 的原生序列化机制(即实现 Serializable 接口)。
Feign 和其他 Spring Cloud 组件在进行远程调用时,会使用 HTTP 协议,并且通常结合了如 JSON 或 XML 等格式的 HTTP 消息转换器来序列化和反序列化对象。
当一个服务调用另一个服务时,Feign 客户端会将 Java 对象转换为 JSON(或其他格式),然后通过 HTTP 请求发送。接收方的服务会将这些 JSON 数据反序列化回 Java 对象。这个过程并不要求 Java 对象实现 Serializable 接口,因为它是基于 HTTP 和消息转换器(如 Jackson JSON 处理库),而不是 Java 原生的序列化机制。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它可以用于数据的传输和转换。JSON 在不同语言和平台之间传输数据时特别有用,因为它易于人阅读和编写,同时也易于机器解析和生成。在许多现代编程环境和网络应用中,JSON 被广泛用于前后端之间的数据传递,以及不同系统之间的数据交换。JSON 格式因其文本形式和自描述性,成为了 Web API 和微服务架构中常用的数据格式。
序列化不一定需要通过实现 Java 的 Serializable 接口来完成。将对象转换成 JSON、XML 或其他格式也是一种序列化的方法。这些方法允许您将对象的状态转换成一种可以存储或传输的格式,而不依赖于 Java 内置的序列化机制。JSON 和 XML 序列化的优点是它们更加灵活,并且与使用不同编程语言的系统之间的兼容性更好。
换成 JSONObject 通常不会携带有关对象原始类的详细信息,例如类名或属性的数据类型。JSONObject 主要是一种以键值对形式存储数据的结构,其中键通常是字符串,对应对象的字段名称,值是字段的值。这意味着对象的结构会被保留,但不包括其作为特定类实例的信息。当从 JSONObject 反序列化时,您需要知道要将其转换成哪种具体的类类型。虽然 JSON 序列化产生的是文本数据,但这些文本数据最终在存储或传输时仍然以二进制的形式存在(因为所有的文件和网络数据传输本质上都是二进制的)。
在 Spring Boot 应用中,当在 Controller 层将对象转换为 JSON 时,通常这是通过使用 Spring MVC 框架的内置功能自动完成的。这里是一个简单的例子:
@RestController 注解表明这个类是一个 Spring MVC Controller,并且所有的响应都会自动转换成 JSON。
ResponseEntity 用于包装响应对象,Spring MVC 会自动使用 Jackson 或其他配置的 JSON 转换库将 MyObject 实例转换成 JSON 格式。
当客户端请求 /myendpoint 时,方法 getMyObject() 会被调用,返回的 MyObject 对象将被自动序列化为 JSON。

在这段 Spring Boot 控制器代码中,序列化主要发生在将 Java 对象转换为 HTTP 响应的 JSON 数据时。这是由 Spring MVC 框架自动处理的。
Spring Boot 应用中,当您的控制器方法返回一个对象时,Spring MVC 使用配置的消息转换器(默认是 Jackson)将对象转换为 JSON 格式。这个过程与对象是否实现 Serializable 无关。
在 Spring MVC 框架中,对象到 JSON 的自动转换是由 HttpMessageConverter 接口的实现类处理的。具体来说:
MappingJackson2HttpMessageConverter:
这是最常用的转换器,用于处理 JSON 数据。它使用 Jackson 库将 Java 对象转换为 JSON,以及将 JSON 转换为 Java 对象。

配置:
在 Spring MVC 中,这些转换器通常是自动配置的。您可以通过配置 WebMvcConfigurer 来自定义这些转换器的行为。
当一个控制器方法返回对象时,Spring MVC 框架会使用合适的 HttpMessageConverter(如 MappingJackson2HttpMessageConverter)来将对象转换为相应格式的响应体(在大多数情况下是 JSON)。
在 Spring MVC 中,以下几个因素通常指示框架自动处理对象到 JSON 的转换:
@RestController 注解:这个注解表明类中的所有方法返回值都应被视为响应体,并且默认会转换为 JSON。
@ResponseBody 注解:在一个使用 @Controller 注解的类中,@ResponseBody 可以用于具体的方法上,表示该方法的返回结果应该被转换为响应体。
内容协商:Spring MVC 根据请求头(如 Accept)进行内容协商,确定使用哪种格式的响应。
配置的消息转换器:如果项目中配置了 MappingJackson2HttpMessageConverter(默认情况下是有的),它会自动用于转换 JSON。
返回类型:方法的返回类型通常是一个 POJO(普通的 Java 对象),Spring MVC 会尝试将其序列化为 JSON。

HTTP(超文本传输协议)可以传输多种类型的数据,包括但不限于:

文本数据:如 HTML 页面、JSON 或 XML 数据、普通文本等。
数字:作为文本的一部分传输,如查询参数或 JSON/XML 的一部分。
图像和多媒体:如 JPEG、PNG 图像,MP3 音频,MP4 视频等。
二进制数据:任何形式的文件数据,如文档、压缩文件等。
表单数据:通过表单提交的数据,包括文本字段、数字、文件上传等。
所以他可以传递string类型(普通文本) 数字,json等,但是不能传递java对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/319598.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式之原型模式【创造者模式】

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

2023年.AI域名销售额达550万美元 2024还要继续涨

根据域名投资专家Elliot Silver的最新文章&#xff0c;2023年公开报道的.AI域名销售额已经达到了550万美元&#xff0c;而2022年和2021年分别为90万美元和120万美元。 Silver观察到过去几年.AI域名销售额呈现逐年增长的趋势&#xff0c;尤其是2023年的销售额相较前两年有了显著…

高效的输电线路故障监测系统:实时监测、预防性维护

在电力系统中&#xff0c;输电线路的健康状态直接关系到电网的安全稳定运行。然而&#xff0c;由于线路的广泛分布和长距离特性&#xff0c;故障的检测和定位变得极其困难。为了解决这一问题&#xff0c;恒峰智慧设计了一种全新的高效输电线路故障监测系统&#xff0c;该系统采…

进程和计划任务

一、什么是程序 是一组计算机能识别和执行的指令&#xff0c;运行于电子计算机上&#xff0c;满足人们某种需求的信息化工具 用于描述进程要完成的功能&#xff0c;是控制进程执行的指令集 二、进程 1.什么是进程 进程&#xff1a;正在运行中的程序&#xff0c;加载到内存…

静态网页课程设计——十二花信(花朵科普)(HTML+CSS+JavaScript)

前言 使用技术&#xff1a;HTMLCSSJS 主要内容&#xff1a;对十二个月每个月的适应季节的花朵进行科普。 主要内容 1、首页 首页顶部由标题栏和一张花朵的图片组成。 下半部分对十二花信进行了简单的科普介绍&#xff0c;分别为一月梅花、二月杏花、三月桃花等等。。 部…

Java 跨平台实现

Java 跨平台实现 1. Java虚拟机&#xff08;JVM&#xff09;2. 中间代码&#xff08;字节码&#xff09;3. Write Once, Run Anywhere (WORA)4. Java 标准库5. 安全性与隔离6. Java Community Process (JCP) Java 的跨平台性主要是通过以下几个关键机制来实现的&#xff1a; 1…

Java设计模式:状态模式

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

天融信TOPSEC Cookie 远程命令执行漏洞

产品介绍 天融信TopSec 安全管理系统&#xff0c;是基于大数据架构&#xff0c;采用多种技术手段收集各类探针设备安全数据&#xff0c;围绕资产、漏洞、攻击、威胁等安全要素进行全面分析&#xff0c;提供统一监测告警、集中策略管控、协同处置流程&#xff0c;实现客户等保合…

GZ075 云计算应用赛题第5套

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷5 某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenSt…

Vue: 多个el-select不能重复选择相同属性

一、场景 1.需求&#xff1a; 用户可自由选择需要修改的对象并同时修改多个属性&#xff0c;需要校验修改对象不能重复选择&#xff0c;但是可供修改属性是固定的 2.目标效果&#xff1a; 二、实现 1.主要代码&#xff1a; <template><el-selectv-model"se…

SV-DJS-I13 深圳锐科达电梯 IP 五方对讲规格书

SV-DJS-I13 深圳锐科达电梯 IP 五方对讲规格书 DJS-I13 是专门对行业用户需求研发的一款 SIP 电梯五方对讲。它不仅有稳定性 好、电信级音质的优点&#xff0c;且完美兼容当下所有基于 SIP 的主流 IPPBX/软交换/IMS 平台, 如 Asterisk, Broadsoft, 3CX, Elastix 等。它集…

redis 三主六从高可用dockerswarm高级版(不固定ip)

redis集群(cluster)笔记 redis 三主三从高可用集群docker swarm redis 三主六从高可用docker(不固定ip) redis 三主六从高可用dockerswarm高级版(不固定ip) 此博客解决&#xff0c;redis加入集群后&#xff0c;是用于停掉后重启&#xff0c;将nodes.conf中的旧的Ip替换为新的…