神奇的Serializable接口,为什么有时候网络传输不用实现Serializable,有时候又需要?

news2024/11/15 9:27:43

大家好,这里是小奏,觉得文章不错可以关注公众号小奏技术

背景

其他大家在初学java的时候肯定是接触过Serializable接口的,这个接口是一个标记接口,没有任何方法,只是一个标记,用来标记一个类可以被序列化,可以被网络传输,可以被持久化。

public interface Serializable {
}

一些传统的草台班子的解释就是,你要网络传输就要实现Serializable接口,但是这个解释并不准确

因为有时候我们发现不实现Serializable接口进行网络传输也不会报错,但是有时候又需要实现Serializable接口,否则会报错,那么底什么时候需要实现Serializable接口呢?

比如我们使用spring boot框架在controller层返回一个json数据,这个时候我们并不需要实现Serializable接口

比如我们使用redisson的发布订阅功能传输的对象又需要实现Serializable接口(使用默认的序列化MarshallingCodec)

如果是抱着能用就行的态度也是很简单,一把梭,只要网络传输就实现Serializable接口

如果想深入了解我们就可以继续向下看下去

什么情况下的网络传输需要实现Serializable接口

大家都知道Serializable接口是java原生提供的接口,那么就说明如果是使用java原生的网络传输方式就需要实现Serializable接口

使用java原生的网络传输对象就需要实现Serializable,如果只是基本类型或者字符串则不需要

这里我们以RMI为例 ,使用RMI传输java对象的的时候就需要需要实现Serializable接口

RMI传输demo

这里我们简单基于RMI传输一个对象,来看看效果,演示下不实现Serializable接口的情况

首先我们实现一个远程接口RemoteInterface

  • RemoteInterface
public interface RemoteInterface extends Remote {
    
    String sayHello(XiaoZou xiaoZou) throws RemoteException;
}

之后提供一个远程接口调用的实现类

  • RemoteImpl
public class RemoteImpl extends UnicastRemoteObject implements RemoteInterface {
    
    protected RemoteImpl() throws RemoteException {
        super();
    }

    @Override
    public String sayHello(XiaoZou xiaoZou) throws RemoteException {
        return "Hello, " + xiaoZou.getName() + "!";
    }
}

注意这里我们传输的对象是XiaoZou

  • XiaoZou
public class XiaoZou implements Serializable {
    
    private String name;
    
    private String age;

    public XiaoZou() {
    }

    public XiaoZou(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

这就是我们要传输的对象,这个对象我们会进行演示实现Serializable接口和不实现Serializable接口的区别

创建一个RMI服务端

  • XiaoZouServer
public class XiaoZouServer {

    public static void main(String[] args) {
        try {
            RemoteInterface stub = new RemoteImpl();
            Registry registry = LocateRegistry.createRegistry(1099);
            registry.rebind("RemoteInterface", stub);
            System.out.println("Server is ready");
        } catch (Exception e) {
            System.err.println("Server exception: " + e);
            e.printStackTrace();
        }
    }
}

创建一个RMI客户端

public class XiaoZouClient {

    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.getRegistry("localhost", 1099);
            RemoteInterface stub = (RemoteInterface) registry.lookup("RemoteInterface");
            String response = stub.sayHello(new XiaoZou("小奏", "18岁"));
            System.out.println("Response from server: " + response);
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

结果

  • 正常实现Serializable接口的情况

client运行结果: Response from server: Hello, 小奏!

  • 不实现Serializable接口的情况

可以看到直接报错java.io.NotSerializableException

为什么spring boot网络传输对象不用实现Serializable接口

到这里我们已经非常清楚的知道了如果使用java原生的序列化方式就需要实现Serializable接口,然后spring boot中编写接口默认使用的是json序列化方式,所以不需要实现Serializable接口

为什么dubbo默认不是java原生序列化方式也需要实现Serializable接口

dubbo 3.x默认使用的序列化方式是hessian2Hessian不是java原生的,为什么也要实现Serializable接口呢?否者就会报错

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/protocol/hessian/

如果默认我们不实现Serializable
就会报错

ause: org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: not support none serializable class com.xiaozoudubbo.dto.XiaoZou

原因很简单,因为dubbo存在Serializable接口检查机制

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/security/class-check/

Serializable接口检查模式分为两个级别:true 开启,false 关闭。开启检查后会拒绝反序列化所有未实现 Serializable 的类。

Dubbo 中默认配置为true开启检查。

所以如果我们想要在dubbo不用实现Serializable接口,我们可以关闭dubboSerializable接口检查机制

spring boot中我们仅仅需要添加配置dubbo.application.check-serializable=true即可

总结

如果使用java原生的网络传输方式(原生序列化方式)传输java对象就需要实现Serializable接口

其他的更现代化的序列化方式一般都不需要实现Serializable接口,比如jsonprotobufhessian2等等

我们使用dubbo的时候默认是需要实现Serializable接口的,因为dubbo存在Serializable接口检查机制,可以通过关闭dubboSerializable接口检查机制来解决这个问题

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入解析代理模式:静态代理、JDK 动态代理和 CGLIB 的全方位对比!

代理模式(Proxy Pattern)是一种结构型设计模式,它提供了对象的替身,即代理对象来控制对实际对象的访问。通过代理对象,可以在不修改目标对象的情况下,扩展或控制其功能。例如,代理模式可以用于延…

JDBC的介绍和连接MySQL数据库

目录 1. 为什么学习JDBC 1.1 数据存储​编辑​编辑 1.2 数据操作​编辑 2. JDBC概述 2.1 JDBC概念 2.2 JDBC 核心组成 3. 实现 JDBC 3.1 JDBC 搭建步骤 3.2 详细演示 3.3 核心API 3.3.1 Driver​ 3.3.2 Connection​ 3.3.3 Statament​ 3.3.4 PreparedStatement …

嵌入式单片机中can总线调试方法

大家好,今天将向大家介绍如何使用STM32F4自带的CAN控制器实现两个开发板之间的CAN通信。 1.CAN CAN是控制器局域网络(Controller Area Network, CAN)的简称,是由以研发和生产汽车电子产品著称的德国BOSCH公司开发的,并最终成为国际标准(ISO 11898),是国际上应用最广泛的…

大模型笔记03--快速体验dify

大模型笔记03--快速体验dify 介绍部署&测试部署 dify测试dify对接本地ollama大模型对接阿里云千问大模型在个人网站中嵌入dify智能客服 注意事项说明 介绍 Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)…

优化 OR 条件过多导致的查询超时

优化 OR 条件过多导致的查询超时 文章目录 优化 OR 条件过多导致的查询超时背景问题分析方案分析方案一:入参去重方案二:分页或者分批查询方案三:UNION 代替 OR方案四:IN 代替 OR1. 分别对列进行 IN 查询,在代码中进行…

同一Python脚本中训练多个模型时的 wandb 配置错误解决方案

文章目录 摘要背景介绍报错信息wandb 模型训练名 摘要 在机器学习项目中,使用Python脚本训练多个模型时,可能会遇到WandB(Weights and Biases)配置错误,尤其是在训练多个模型参数大小不一致的情况下。 本文将介绍如何…

Vue学习记录之三(ref全家桶)

ref、reactive是在 setup() 声明组件内部状态用的&#xff0c; 这些变量通常都要 return 出去&#xff0c;除了供 < template > 或渲染函数渲染视图&#xff0c;也可以作为 props 或 emit 参数 在组件间传递。它们的值变更可触发页面渲染。 ref &#xff1a;是一个函数&…

Get包中的根组件

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容&#xff0c;本章回中将介绍GetMaterialApp组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…

Unity webgl跨域问题 unity使用nginx设置跨域 ,修改请求头

跨域 什么是跨域 跨域是指浏览器因安全策略限制&#xff0c;阻止一个域下的网页访问另一个域下的资源。 一些常见的跨域情况&#xff1a; 协议不同 从 http://example.com 请求 https://example.com。域名不同 从 http://example.com 请求 http://anotherdomain.com。端口不…

Village Exteriors Kit 中世纪乡村房屋场景模型

此模块化工具包就是你一直在寻找的适合建造所有中世纪幻想村庄和城市建筑所需要的工具包。 皇家园区 - 村庄外饰套件的模型和纹理插件资源包 酒馆和客栈、魔法商店、市政大厅、公会大厅、布莱克史密斯锻造厂、百货商店、珠宝商店、药店、草药师、银行、铠甲、弗莱切、马厩、桌…

list从0到1的突破

目录 前言 1.list的介绍 2.list的常见接口 2.1 构造函数&#xff08; (constructor)&#xff09; 接口说明 2.2 list iterator 的使用 2.3 list capacity 2.4 list element access 2.5 list modifiers 3.list的迭代器失效 附整套练习源码 结束语 前言 前面我们学习…

Defining Constraints with ObjectProperties

步骤4&#xff1a;使用对象定义约束 物业 您可以创建时间和放置约束&#xff0c;如本教程所示。你也可以 更改单元格的属性以控制Vivado实现如何处理它们。许多 物理约束被定义为单元对象的属性。 例如&#xff0c;如果您在设计中发现RAM存在时序问题&#xff0c;为了避免重新合…

C语言代码练习(第二十六天)

今日练习&#xff1a; 数据的交换输出输入 n 个数&#xff0c;找出其中最小的数&#xff0c;将它与最前面的数交换后输出这些数 输入一个英文句子&#xff0c;将每个单词的第一个字母改成大写字母 输入一个十进制数 N &#xff0c;将它转换成 R 进制数输出 数据的交换输出输入 …

阿里OSS对象存储服务,实现图片上传回显

阿里OSS对象存储服务 OSS服务1. 创建buckte2. 获取accesskey3. 参照官方SDK编写程序安装SDK 4. 程序编写5. 封装6. 在spring中调用 OSS服务 阿里云对象存储 OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;提供最…

利用JS数组根据数据生成柱形图

要求 <html> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

精准识别,高效管理:工服识别AI检测算法在多场景中的应用优势

随着人工智能技术的快速发展&#xff0c;其在各个行业的应用也日益广泛。特别是在工业生产和安全监管领域&#xff0c;工服识别AI检测算法凭借其高效、精准的特点&#xff0c;成为提升生产效率、保障工作人员安全的重要手段。本文将详细介绍TSINGSEE青犀AI智能分析网关V4工服识…

Hibernate基础

Hibernate基础总结 有利的条件和主动的恢复产生于再坚持一下的努力之中&#xff01; 好久没更新了&#xff0c;今天入门了Hibernate&#xff0c;由于之前学习了MyBatis&#xff0c;初步感觉二者的底层实现思想有很多相似之处&#xff0c;下面让我们以一个入门Demo的形式感受一…

3.Java高级编程实用类介绍(一)

三、Java高级编程实用类介绍(一) 文章目录 三、Java高级编程实用类介绍(一)一、枚举类型二、包装类三、Math 一、枚举类型 使用enum进行定义 public enum 枚举名字{值1,值2.... }二、包装类 每个基本类型在java.lang包中都有一个相应的包装类 /** new包装类&#xff08;字符…

【C++笔记】类和对象的深入理解(三)

【C笔记】类和对象的深入理解(三) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(三)前言一.日期类的实现1.1声明和定义分离1.2日期类整数1.3日期类整数1.4日期类-整数1.5日期类-日期1.6复用对…

并发安全与锁

总述 这篇文章&#xff0c;我想谈一谈自己对于并发变成的理解与学习。主要涉及以下三个部分&#xff1a;goroutine&#xff0c;channel以及lock 临界区 首先&#xff0c;要明确下面两组概念 并发和并行 并行&#xff1a;指几个程序每时每刻都同时进行 并发&#xff1a;指…