• 防止反序列创建对象漏洞


    ******************************************正确写法******************************************************
    package com.example.SpringBootTest1.shejimoshi.singleton;
    import java.io.ObjectStreamException;
    import java.io.Serializable;
    public class InnerclassSingleton implements Serializable {
    public static final long serialVersionUID = 42L;
    private InnerclassSingleton() {
    if (InnerclassSingleton.getInstance() != null) {
    throw new RuntimeException("单例模式不允许创建多个实例");
    }
    };

    private static class Singleton {
    private static final InnerclassSingleton i = new InnerclassSingleton();
    }

    public static InnerclassSingleton getInstance() {
    return Singleton.i;
    }

    Object readResolve() throws ObjectStreamException {
    return InnerclassSingleton.getInstance();
    }
    }

    package com.example.SpringBootTest1.shejimoshi.singleton;
    import java.io.*;
    public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    InnerclassSingleton instance = InnerclassSingleton.getInstance();
    // 序列化
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
    oos.writeObject(instance);
    oos.close();
    // 反序列化
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
    InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
    System.out.println(instance == instance2); // true
    }
    }

    package com.example.SpringBootTest1.shejimoshi.singleton;
    import java.io.ObjectStreamException;
    import java.io.Serializable;
    public class InnerclassSingleton implements Serializable {
    public static final long serialVersionUID = 42L;
    private InnerclassSingleton() {
    if (InnerclassSingleton.getInstance() != null) {
    throw new RuntimeException("单例模式不允许创建多个实例");
    }
    };

    private static class Singleton {
    private static final InnerclassSingleton i = new InnerclassSingleton();
    }

    public static InnerclassSingleton getInstance() {
    return Singleton.i;
    }

    Object readResolve() throws ObjectStreamException {
    return InnerclassSingleton.getInstance();
    }
    int i = 0; // 新增一行代码
    }
    package com.example.SpringBootTest1.shejimoshi.singleton;
    import java.io.*;
    public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    InnerclassSingleton instance = InnerclassSingleton.getInstance();
    // 序列化
    // ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
    // oos.writeObject(instance);
    // oos.close();
    // 反序列化
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
    InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
    System.out.println(instance == instance2); // true (新增了一行代码后打印还是true)
    }
    }
    ****************************************非正常写法**************************************
    public class InnerclassSingleton implements Serializable {
      // public static final long serialVersionUID = 42L;
    private InnerclassSingleton() {
    if (InnerclassSingleton.getInstance() != null) {
    throw new RuntimeException("单例模式不允许创建多个实例");
    }
    };

    private static class Singleton {
    private static final InnerclassSingleton i = new InnerclassSingleton();
    }

    public static InnerclassSingleton getInstance() {
    return Singleton.i;
    }

    Object readResolve() throws ObjectStreamException {
    return InnerclassSingleton.getInstance();
    }
    }

    package com.example.SpringBootTest1.shejimoshi.singleton;
    import java.io.*;
    public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    InnerclassSingleton instance = InnerclassSingleton.getInstance();
            // 序列化
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
    oos.writeObject(instance);
    oos.close();
    // 反序列化
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
    InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
    System.out.println(instance == instance2); // true
    }
    }

    public class InnerclassSingleton implements Serializable {
      // public static final long serialVersionUID = 42L;
    private InnerclassSingleton() {
    if (InnerclassSingleton.getInstance() != null) {
    throw new RuntimeException("单例模式不允许创建多个实例");
    }
    };

    private static class Singleton {
    private static final InnerclassSingleton i = new InnerclassSingleton();
    }

    public static InnerclassSingleton getInstance() {
    return Singleton.i;
    }

    Object readResolve() throws ObjectStreamException {
    return InnerclassSingleton.getInstance();
    }
    int i = 0; // 新增一行代码
    }

    package com.example.SpringBootTest1.shejimoshi.singleton;
    import java.io.*;
    public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    InnerclassSingleton instance = InnerclassSingleton.getInstance();
    // 序列化
    // ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
    // oos.writeObject(instance);
    // oos.close();

    // 反序列化
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
    InnerclassSingleton instance2 = (InnerclassSingleton) ois.readObject();
    System.out.println(instance == instance2); // false (由于新增了一行代码,会打印false)
    }
    }

    总结: 如果需要进行网络传输, 需要实现序列化接口, 并且指定一个序列化编号(反序列化时, 尽管类代码有变动, 还是会返回指定编号的对象)
  • 相关阅读:
    SpringCloud Alibaba Nacos详解
    常见设计模式
    Mybatis TypeHandler类型处理器
    Mybatis存取json字段转为Java对象方案
    Spring AOP 切面编程详解
    Spring Data 、Spring Data JPA 、Hibernate之间的关系及SpringDataJPA简单使用
    28张图解 | 互联网究竟是「如何连接,如何进行通信」的?
    Java代码实现 图片添加多行水印且自动换行
    SpringMVC 快速入门
    获取本地磁盘得到.txt文件
  • 原文地址:https://www.cnblogs.com/ladeng19/p/15831341.html
Copyright © 2020-2023  润新知