Effective Java之考虑用序列化代理代理序列化实例(七十八)
我们知道,实现了序列化的类。在反序列化时,实例的创建是由readObject方法来完成的。由于这是一个不同于构造函数的创建类实例的通道,因此在构造函数中的状态约束条件在readObjetc中也得一条不落下的实现。这很让人头大。
而且readObject的出现,让伪字节流攻击和内部域的盗用攻击成为可能。伪字节流攻击就是伪造一个字节流,通过readObject读取,内部域的盗用攻击是指用一个外部类包含该类,用外部类的字段去指向该类的可变对象。
因此这里介绍一种模式,将实例的反序列化也交给改造函数来完成,即序列化代理模式。要想稳健的将带有重要约束条件的对象序列化时,这种模式可能是最容易的方法。代码如下:
public class Period implements Serializable{ private static final long serialVersionUID = 1L; private final Date start; private final Date end; public Period(Date start, Date end) { if(null == start || null == end || start.after(end)){ throw new IllegalArgumentException("请传入正确的时间区间!"); } this.start = start; this.end = end; } public Date start(){ return new Date(start.getTime()); } public Date end(){ return new Date(end.getTime()); } @Override public String toString(){ return "起始时间:" + start + " , 结束时间:" + end; } /** * 序列化外围类时,虚拟机会转掉这个方法,最后其实是序列化了一个内部的代理类对象! * @return */ private Object writeReplace(){ System.out.println("进入writeReplace()方法!"); return new SerializabtionProxy(this); } /** * 如果攻击者伪造了一个字节码文件,然后来反序列化也无法成功,因为外围类的readObject方法直接抛异常! * @param ois * @throws InvalidObjectException */ private void readObject(ObjectInputStream ois) throws InvalidObjectException{ throw new InvalidObjectException("Proxy required!"); } /** * 序列化代理类,他精确表示了其当前外围类对象的状态!最后序列化时会将这个私有内部内进行序列化! */ private static class SerializabtionProxy implements Serializable{ private static final long serialVersionUID = 1L; private final Date start; private final Date end; SerializabtionProxy(Period p){ this.start = p.start; this.end = p.end; } /** * 反序列化这个类时,虚拟机会调用这个方法,最后返回的对象是一个Period对象!这里同样调用了Period的构造函数, * 会进行构造函数的一些校验! */ private Object readResolve(){ System.out.println("进入readResolve()方法,将返回Period对象!"); // 这里进行保护性拷贝! return new Period(new Date(start.getTime()), new Date(end.getTime())); } }
思路很清晰,拒绝外围类的readObject的调用,也就防止了伪字节流攻击和内部域的盗用攻击,同时无需保护性拷贝。
Effective Java之考虑用序列化代理代理序列化实例(七十八)相关推荐
- Java程序员从笨鸟到菜鸟之(七十八)细谈Spring(七)spring之JDBC访问数据库及配置详解
利用spring访问数据库是我们ssh程序中必不可少的步骤,在没有hibernate之前,我们一般都用jdbc访问数据库,所以用jdbc访问数据库必不可少的要进行一些配置,spring中为我们提供了访 ...
- java责任链模式做优惠_Java设计模式菜鸟系列(十八)责任链模式建模与实现
责任链模式(ChainOfResponsibility): 有多个对象,每个对象持有下一个对象的引用,形成一条链,请求在这条链上传递,直到某一对象决定处理该请求,但是发出者并不清楚最终哪个对象会处理该 ...
- java不想出差_您不想错过的十大Java书籍
java不想出差 我们通过阅读书籍并进行实验来学习. 因此,必须选择最佳的可用选项. 在本文中,我想与一些书分享我的经验,以及它们如何帮助您发展成为Java开发人员. 让我们从头开始,对于任何Java ...
- Effective Java读书笔记八:序列化(74-78)
第74条:谨慎地实现Serializable接口 对象序列化API,它提供了一个框架,用来将对象编码成字节流,并从字节流编码中重新构建对象.将一个对象编码成一个字节流,称作将该对象序列化,相反的处理过 ...
- Effective java 总结11 - 序列化
Effective java 总结11 - 序列化 序列化:对象 -> 字节流 反序列化:字节流 -> 对象 第85条 其他方法优先于java序列化 序列化的根本问题在于:攻击面过于庞大, ...
- Java设计模式之结构型:代理模式
前言: 我们一般在租房子时会去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做:再比如我们打官司需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们 ...
- java动态代理--代理接口无实现类
转载自 http://blog.csdn.net/zhu_tianwei/article/details/40076391 使用通过接口定义,或解析接口注解等完成相关功能,如mybatis的SqlSe ...
- Effective Java之考虑自定义的序列化模式(七十五)
为什么自定义序列化? 这里直接举一个书上的例子 public final class StringList implements Serializable {private int size = 0; ...
- 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试
文章目录 Java的静态代理 静态代理的优缺点 ABAP的静态代理 Spring AOP的动态代理 JDK动态代理的优缺点 CGLIB动态代理的优缺点 ABAP CGLIB的模拟实现 ABAP Pre ...
最新文章
- Spring4-JdbcDaoSupport-查询单列
- redis.conf配置选项如下
- Hibernate Cascade 属性
- Hyperledger Fabric基础知识
- 用new关键字对一个String 变量赋值和用literal值直接赋值有什么不同(转)
- 【渝粤教育】国家开放大学2018年秋季 0716-22T工程建设法规 参考试题
- 图像超分辨率也能改善天气预报?没错!
- 用易拉罐做机器人教程_不会c4d就做不出3d设计?用ps照样可以,教程在这里
- python2逐步转向python3之小程序实践学习
- Http——Post上传文件并传递其他参数信息
- LayoutInflater原理分析
- UTF-8编码占几个字节?
- DSP 脉冲检测CAP
- 对话李春龙:如何用Kubernetes管理有状态服务
- CuraEngine源码编译
- 2022年大数据BI工程师项目实训介绍
- 怎样实现cmd命令窗口的快速复制粘贴操作
- 2019中兴校招流程回顾总结
- mysql-8.0.16-winx64_mysql-8.0.16-winx64的最新安装教程
- WPS整段缩进(类似代码格式)