「漫画」避免使用Java序列化
程序员文章站
2022-04-02 10:46:46
...
原创:享学课堂讲师
转载请声明出处!
下面我们就一起来看看 JDK 默认的序列化到底存在着哪些缺陷:
1. 无法跨语言
Java 序列化目前只适用基于 Java 语言实现的框架,其它语言大部分都没有使用 Java 的序列化框架,也没有实现 Java 序列化这套协议。因此,如果是两个基于不同语言编写的应用程序相互通信,则无法实现两个应用服务之间传输对象的序列化与反序列化。
2. 易被攻击
Java 官网安全编码指导方针中说明:“对不信任数据的反序列化,从本质上来说是危险的,应该予以避免”。可见 Java 序列化是不安全的。
3. 序列化性能太差
序列化的速度也是体现序列化性能的重要指标,如果序列化的速度慢,就会影响网络通信的效率,从而增加系统的响应时间。我们再来通过下面这个例子,来对比下 Java 序列化与 NIO 中的 ByteBuffer 编码的性能:
Java 序列化
User user = new User();
user.setUserName("test");
user.setPassword("test");
long startTime = System.currentTimeMillis();
for(int i=0; i<1000; i++)
{
ByteArrayOutputStream os =
new ByteArrayOutputStream();
ObjectOutputStream out =
new ObjectOutputStream (os);
out.writeObject(user);
out.flush();
out.close();
byte
[] testByte = os.toByteArray();
os.close();
}
long endTime =
System.currentTimeMillis();
System.out.print("ObjectOutputStream 序列化时间:"+ (endTime - startTime)
ByteBuffer
long
startTime1 = System
.currentTimeMillis();
for(int i=0; i<1000; i++)
{
ByteBuffer
byteBuffer = ByteBuffer
.allocate( 2048);
byte[] userName = user.getUserName().getBytes();
byte[] password = user.getPassword().getBytes();
byteBuffer.putInt(userName.length);
byteBuffer.put(userName);
byteBuffer.putInt(password.length);
byteBuffer.put(password);
byteBuffer.flip();
byte[] bytes =
new byte [byteBuffer.remaining()];
}
long endTime1 = System
.currentTimeMillis();
System
.out.print(
"ByteBuffer 序列化时间:"+ (endTime1 - startTime1)+ "\n");
运行结果:
ObjectOutputStream 序列化时间:38 ByteBuffer 序列化时间:7
通过以上案例,我们可以清楚地看到:Java 序列化中的编码耗时要比 ByteBuffer 长很多
喜欢本文的话可以关注我们的官方账号,第一时间获取资讯。
你的关注是对我们更新最大的动力哦~
推荐阅读
-
java序列化和serialVersionUID的使用方法实例
-
详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)
-
解决Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题
-
Java 为什么要避免使用finalizer和Cleaner
-
Java在MVC开发模式中使用try-catch以及throws避免踩坑
-
Java多线程——JUC ReentrantLock使用详解一篇就够,以及使用ReentrantLock避免死锁情况的产生
-
go 字符串反序列化成对象数组_使用java将json文件反序列化成java对象
-
使用Java 8 Optional避免空指针异常
-
java8使用Optional来避免空指针异常(简化代码)
-
【小家java】java8新特性之---Optional的使用,避免空指针,代替三目运算符