当前位置: 首页> 汽车> 维修 > 神奇的Serializable接口,为什么有时候网络传输不用实现Serializable,有时候又需要?

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

时间:2025/7/9 11:12:09来源:https://blog.csdn.net/qq_42651904/article/details/142318091 浏览次数: 0次

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

背景

其他大家在初学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();}@Overridepublic 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接口检查机制来解决这个问题

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: