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 和 setters
    public 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 和 setters
    public 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对象

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

初始数字孪生

文章目录 概念定义 架构框图 基本要求 功能要求 服务应用 参考文献 概念定义 数字孪生&#xff08;digital twin&#xff09;&#xff0c;是指具有保证物理状态和虚拟状态之间以适当速率和精度同步的数据连接的特定目标实体的数字化表达。 架构框图 数字孪生的整体架构&a…

C# halcon 工业产品尺寸测量

产品检测 这段代码是一个基于HalconDotNet的Windows窗体应用程序&#xff0c;主要用于图像处理和测量。以下是对代码的一些总结&#xff1a; 1. **图像显示与加载&#xff1a;** - 使用HalconDotNet库进行图像处理。 - 通过OpenFileDialog实现图像文件的选择和加载。 …

Vue v-html中内容图片过大自适应处理

之前图片如下&#xff0c;图片已经超出了页面的展示范围 对v-html增加样式处理 <div class"body padding-l scroll " v-html"docData.content"> </div><style scoped>.body >>> img {max-width: 100% ;} </style>…

[书生·浦语大模型实战营]——书生·浦语大模型全链路开源体系

大模型成为发展通用人工智能的重要途径 书生浦语大模型开源历程 书生浦语模型性能 从模型到应用 应用例子&#xff1a;智能客服/个人助手/行业应用 实现流程&#xff1a; 开源开放体系&#xff1a; 1.数据——书生万卷 价值观对齐这个挺有意思嗷&#xff01; 2.预训练工具…

redis复习笔记02(小滴课堂)

分布式缓存Redis6常见核心配置讲解 查看配置文件&#xff1a; 创建配置文件&#xff1a; 配置完我们去验证一下&#xff1a; 启动成功就没有问题了。 可以看到redis日志。 然后我们就可以连接我们的redis了&#xff1a; 设置了密码就需要密码登录了。 如果登录了错误的密码也无…

搜索Agent方案

为啥需要整体方案&#xff0c;直接调用搜索接口取Top1返回不成嘛&#xff1f;要是果真如此Simple&Naive&#xff0c;New Bing岂不是很容易复刻->.-> 我们先来看个例子&#xff0c;前一阵火爆全网的常温超导技术&#xff0c;如果想回答LK99哪些板块会涨&#xff0c;你…

勒索检测能力升级,亚信安全发布《勒索家族和勒索事件监控报告》

评论员简评 近期(12.08-12.14)共发生勒索事件119起&#xff0c;相较之前呈现持平趋势。 与上周相比&#xff0c;本周仍然流行的勒索家族为lockbit3和8base。在涉及的勒索家族中&#xff0c;活跃程度Top5的勒索家族分别是&#xff1a;lockbit3、siegedsec、dragonforce、8base和…

视频监控可视化云平台EasyCVR智能视频技术优势分析

TSINGSEE青犀视频安防视频管理系统EasyCVR视频智能融合共享平台&#xff0c;是一个支持Windows/Linux(CentOS ubuntu)/国产化系统的视频管理平台。平台可以支持多协议接入&#xff0c;通过视频应用引擎将多种格式的视频数据转换为统一的视频流数据&#xff0c;支持无插件H5直播…

k8s的pod基础

pod:pod是k8s中最小的资源管理组件。 pod也是最小化运行容器化的应用的资源管理对象。 pod是一个抽象的概念&#xff0c;可以理解为一个或者多个容器化应用的集合。 在一个pod当中运行一个容器是最常用的方式。在一个pod当中同时运行多个容器&#xff0c;在一个pod当中可以同…

聊聊分布式会话及实现方案

鲁大猿&#xff0c;寻找精品资料&#xff0c;帮你构建Java全栈知识体系 http://www.jiagoujishu.cn 基础概念 Session Cookie 会话方案比较简单&#xff0c;这里我在网上找了点资料&#xff0c;再回顾下基础吧。 为什么要产生Session http协议本身是无状态的&#xff0c;客户…

《绝地求生》改名卡快速获得方法 绝地求生改名卡怎么获得

《绝地求生》改名卡是很多小伙伴所在意的物品&#xff0c;购买通行证后需要提升一定的等级才能入手&#xff0c;而怎么升级最快最划算呢&#xff1f;今天闲游盒带来“米奇”分享的《绝地求生》改名卡快速获得方法&#xff0c;赶紧来试试吧。 吃鸡刚刚迎来了更新&#xff0c;通行…

八大算法排序@冒泡排序(C语言版本)

冒泡排序 概念 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单直观的排序算法&#xff0c;它重复地遍历待排序序列&#xff0c;一次比较两个相邻的元素&#xff0c;如果它们的顺序错误就将它们交换过来。通过多次的遍历&#xff0c;使得最大的元素逐渐移动到待排序序…

Windows—常用DOS命令

解释&#xff1a;DOS命令即面向磁盘的操作命令 进入DOS页面&#xff1a;快捷键“winR”&#xff0c;输入cmd help命令 help 【命令名】可查看其他命令的解释&#xff0c;直接输入help也可以查看部分命令 另外&#xff0c;如果输入help显示help不是内部或外部命令&#xff0c;…

ACCESS从零入门教程

最近&#xff0c;在公司实习自学了一款简单的access数据库软件&#xff0c;下面是自己的一些学习心得过程&#xff0c;供大家参考。 一、access导入数据 两种方法&#xff1a; 1、直接复制&#xff0c;crtl-c/v即可 2、若数据量较大&#xff0c;可以从access内部进行导入&am…

c++语言基础18-开房门

题目描述 假设你手里有一串钥匙&#xff0c;这串钥匙上每把钥匙都有一个编号&#xff0c;对应着一个房门的编号。现给你一个房门编号&#xff0c;你需要判断是否能够打开该房门。 输入描述 测试数据共有多组。 第一行为一个整数 s&#xff0c;表示共有多少组测试数据。 每组第一…

c# OpenCvSharp透视矫正参数调整器

透视矫正不够智能化&#xff0c;每次都要进行局部参数调整&#xff0c;不便于程序使用&#xff0c;程序流程还是那几个步骤&#xff1b; 1、读取图像、灰度化 2、高斯滤波 3、二值化 4、边缘检测 灰度化图 上个图看看经过调整透视矫正边缘检测结果我还是挺满意的 发现一个…

基于springboot智慧食堂管理系统源码和论文

随着Internet的发展&#xff0c;人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化&#xff0c;网络化和电子化。网上管理&#xff0c;它将是直接管理“智慧食堂”系统的最新形式。本论文是以构建“智慧食堂”系统为目标&#xff0c;使用java技术制作&…

Java Synchronized 和 ReentrantLock

目录 介绍 synchronized synchronized 修饰实例方法 修饰静态类方法 synchronized 修饰代码块 实现细节 ReentrantLock ReentrantLock 基本使用 公平锁实现 读写锁&#xff08;ReentrantReadWriteLock&#xff09; 1. 创建读写锁对象&#xff1a; 2. 通过读写锁对象…

IDS 和 IPS:了解异同

IDS 和 IPS 是至关重要的网络安全技术&#xff0c;经常被混淆或互换使用。那么&#xff0c;IDS 和 IPS 之间有什么区别&#xff0c;哪一种是最适合您组织需求的选择呢&#xff1f; 什么是IDS&#xff08;入侵检测系统&#xff09;&#xff1f; 入侵检测系统 (IDS) 是一种网络…

【管理篇 / 登录】❀ 06. macOS下使用USB配置线登录 ❀ FortiGate 防火墙

【简介】飞塔防火墙上都会配有CONSOLE接口&#xff0c;包装里都会配置一根USB配置线&#xff0c;通过这个接口和这根线&#xff0c;我们可以用命令的方式登录飞塔防火墙进行操作。随着苹果电脑的普及&#xff0c;我们来学习一下&#xff0c;如果在MAC OS中用配置线登录飞塔防火…