java 防止反射_Java设计模式(一):单例模式,防止反射和反序列化漏洞
一、懒汉式单例模式,解决反射和反序列化漏洞
package com.iter.devbox.singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;
/**
* 懒汉式(如何防止反射和反序列化漏洞)
* @author Shearer
*
*/
public class SingletonDemo6 implements Serializable{
// 类初始化时,不初始化这个对象(延迟加载,真正用的时候再创建)
private static SingletonDemo6 instance;
private SingletonDemo6() {
// 防止反射获取多个对象的漏洞
if (null != instance) {
throw new RuntimeException();
}
}
// 方法同步,调用效率低
public static synchronized SingletonDemo6 getInstance() {
if (null == instance)
instance = new SingletonDemo6();
return instance;
}
// 防止反序列化获取多个对象的漏洞。
// 无论是实现Serializable接口,或是Externalizable接口,当从I/O流中读取对象时,readResolve()方法都会被调用到。
// 实际上就是用readResolve()中返回的对象直接替换在反序列化过程中创建的对象。
private Object readResolve() throws ObjectStreamException {
return instance;
}
}
package com.iter.devbox.singleton;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Client2 {
public static void main(String[] args) throws Exception {
SingletonDemo6 sc1 = SingletonDemo6.getInstance();
SingletonDemo6 sc2 = SingletonDemo6.getInstance();
System.out.println(sc1); // sc1,sc2是同一个对象
System.out.println(sc2);
// 通过反射的方式直接调用私有构造器(通过在构造器里抛出异常可以解决此漏洞)
/*Classclazz = (Class) Class.forName("com.iter.devbox.singleton.SingletonDemo6");
Constructorc = clazz.getDeclaredConstructor(null);
c.setAccessible(true); // 跳过权限检查
SingletonDemo6 sc3 = c.newInstance();
SingletonDemo6 sc4 = c.newInstance();
System.out.println(sc3); // sc3,sc4不是同一个对象
System.out.println(sc4);*/
// 通过反序列化的方式构造多个对象(类需要实现Serializable接口)
// 1. 把对象sc1写入硬盘文件
FileOutputStream fos = new FileOutputStream("object.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(sc1);
oos.close();
fos.close();
// 2. 把硬盘文件上的对象读出来
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.out"));
// 如果对象定义了readResolve()方法,readObject()会调用readResolve()方法。从而解决反序列化的漏洞
SingletonDemo6 sc5 = (SingletonDemo6) ois.readObject();
// 反序列化出来的对象,和原对象,不是同一个对象。如果对象定义了readResolve()方法,可以解决此问题。
System.out.println(sc5);
ois.close();
}
}
二、静态内部类式单例模式(解决反射和反序列化漏洞)
package com.iter.devbox.singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;
/**
* 静态内部类实现方式(也是一种懒加载方式)
* 这种方式:线程安全,调用效率高,并且实现了延迟加载
* 解决反射和反序列化漏洞
* @author Shearer
*
*/
public class SingletonDemo7 implements Serializable{
private static class SingletonClassInstance {
private static final SingletonDemo7 instance = new SingletonDemo7();
}
// 方法没有同步,调用效率高
public static SingletonDemo7 getInstance() {
return SingletonClassInstance.instance;
}
// 防止反射获取多个对象的漏洞
private SingletonDemo7() {
if (null != SingletonClassInstance.instance)
throw new RuntimeException();
}
// 防止反序列化获取多个对象的漏洞
private Object readResolve() throws ObjectStreamException {
return SingletonClassInstance.instance;
}
}
package com.iter.devbox.singleton;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
public class Client3 {
public static void main(String[] args) throws Exception {
SingletonDemo7 sc1 = SingletonDemo7.getInstance();
SingletonDemo7 sc2 = SingletonDemo7.getInstance();
System.out.println(sc1); // sc1,sc2是同一个对象
System.out.println(sc2);
// 通过反射的方式直接调用私有构造器(通过在构造器里抛出异常可以解决此漏洞)
Classclazz = (Class) Class.forName("com.iter.devbox.singleton.SingletonDemo7");
Constructorc = clazz.getDeclaredConstructor(null);
c.setAccessible(true); // 跳过权限检查
SingletonDemo7 sc3 = c.newInstance();
SingletonDemo7 sc4 = c.newInstance();
System.out.println("通过反射的方式获取的对象sc3:" + sc3); // sc3,sc4不是同一个对象
System.out.println("通过反射的方式获取的对象sc4:" + sc4);
// 通过反序列化的方式构造多个对象(类需要实现Serializable接口)
// 1. 把对象sc1写入硬盘文件
FileOutputStream fos = new FileOutputStream("object.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(sc1);
oos.close();
fos.close();
// 2. 把硬盘文件上的对象读出来
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.out"));
// 如果对象定义了readResolve()方法,readObject()会调用readResolve()方法。从而解决反序列化的漏洞
SingletonDemo7 sc5 = (SingletonDemo7) ois.readObject();
// 反序列化出来的对象,和原对象,不是同一个对象。如果对象定义了readResolve()方法,可以解决此问题。
System.out.println("对象定义了readResolve()方法,通过反序列化得到的对象:" + sc5);
ois.close();
}
}
java 防止反射_Java设计模式(一):单例模式,防止反射和反序列化漏洞相关推荐
- 3种设计模式java小程序_Java设计模式之单例模式(3种实现方式)
饿汉模式 public class Singleton {//实例化private static Singleton instance=new Singleton();private Singleto ...
- java单例模式的七种写法_Java设计模式之单例模式的七种写法
什么是单例模式? 单例模式是一种常见的设计模式,单例模式的写法有很多种,这里主要介绍三种: 懒汉式单例模式.饿汉式单例模式.登记式单例 . 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类 ...
- java connection 单例_Java设计模式之单例模式详解
Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...
- java单例设计模式_Java设计模式之单例模式详解
在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...
- filter java 是单例的吗_JAVA 设计模式之 单例模式详解
单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...
- java设计模式在线视频_Java设计模式之单例模式视频课程
一.概述 多例模式(Multiton Pattern),这种设计模式也属于对象创建型模式,本质上就是单例模式的推广 定义: 一个类有多个实例且由类本身创建和管理自己的实例,并向外部提供访问点. 二. ...
- java 影子实例_java设计模式(四)--单例模式
Singleton最熟悉不过了,下面学习单例模式.转载:http://zz563143188.iteye.com/blog/1847029 单例对象(Singleton)是一种常用的设计模式.在Jav ...
- java单例模式实例_Java设计模式之单例模式 通俗易懂 超详细 【内含案例】
单例模式 什么是单例模式 ? 确保程序中一个类只能被实例化一次,实现这种功能就叫单例模式 单例模式的好处是什么 ? 方便控制对象 节省资源减少浪费 怎么实现单例模式 ? 构造私有化 调用静态方法返回实 ...
- java+单例+恶汉_Java设计模式之单例模式(恶汉式和懒汉式)
/** 单例模式:* 饿汉式:类一加载就创建对象* 懒汉式:用的时候,才去创建对象* 面试题:单例模式的思想是什么?写一个代码体现(我们最好写懒汉式的单例模式给面 /* * 单例模式: * ...
最新文章
- 美国年薪最高的高管是谁?彭博最新薪酬排名出炉,库克只排第二
- CUDA编程快速入门教程
- 有关于GB2312与Unicode的编码位
- Rest Framework:序列化组件
- Just another board game 博弈-vector套vector
- 快捷键截屏_关于Mac电脑截图,你必须要知道的几个快捷键!(错过会后悔哦)...
- LabVIEW2018安装教程
- 大四中软实习笔记20130226
- 将原生SQL功能Hibernate到您的Spring Data Repository中
- e站app改内置hosts_米家踢脚线电暖器E评测:符合现代家居审美 全屋取暖“小钢炮”...
- 公务员计算机考试题库,公务员考试题库
- java访问本地文件_java 读取本地文件 更改
- linux里的vmware16有中文吗,vmware 16.1专业版_linux版本下载_vmware 16.1下载_5分享
- 玩转springboot2.x之异步调用@Async
- 百度云文章的链接地址抓取工具
- python基础——经营第一个项目,如何将python学得更6 ?
- CSS3 3D旋转魔方
- 添加附件测试的测试点
- 阅读笔记0001之聊聊数据分析现状
- linux中sed如何替换换行符,linux sed命令,如何替换换行符“\n”
热门文章
- ActionTileViewController.js
- Price determination entry point - how is 4.85 calculated
- 关于CRM WebClient UI缓存清理的讨论
- Cloud for Customer里employee视图打开时的渲染逻辑
- 一个用Axure开发的安卓Android智能交通app的mockup
- Extension field添加到CDS view上的技术实现
- CM: UPDATE_PAYLOAD_FROM_ADDINSCH
- Java AOP研究之@Aspect注解的工作原理
- 你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧
- python 三维数据绘图_Python中三维坐标空间绘制的实现