博主18年的互联网软件开发经验,从一名程序员小白逐步成为了一名架构师,我想通过平台将经验分享给大家,因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验,晚上进行用心精简、整理、总结、定稿,每天都会整理到12点,为了就是能让大家能够真正了解该技术栈的真正原理,最终从程序员成为一名真正的架构师,写的不一定是全站做好的,但是是全站最用心的~。
以后我会推出一些列的文章,每天都会更新,每天进步一点点,发布顺序【java的api基础、应用、实战】->【java开源技术栈及源码分析】->【java开源技术栈整合】->【java低代码开发平台的建设】
关注【架构师成长之道】 输入“架构师视频课程”,即可免费获得全套架构师全套课程
1.46 ObjectInputValidation
ObjectInputValidation
接口用于在读取对象时验证对象的有效性。在 ObjectInputStream
读取对象之后,如果读取的对象实现了 ObjectInputValidation
接口,则会调用其 validateObject()
方法来验证对象的有效性。如果 validateObject()
方法抛出 InvalidObjectException
,则对象将被视为无效。
ObjectInputValidation 接口介绍:
所有字段:
ObjectInputValidation
接口没有字段。
构造方法:
ObjectInputValidation
接口没有构造方法,因为它是一个接口。
方法摘要:
-
void validateObject() throws InvalidObjectException
:验证对象的有效性。
简单使用例子:
下面是一个简单的示例,演示了如何实现 ObjectInputValidation
接口以验证对象的有效性:
javaCopy code import java.io.*; public class ObjectInputValidationExample { static class Person implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 1L; private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public void validateObject() throws InvalidObjectException { if (age < 0) { throw new InvalidObjectException("Age cannot be negative"); } } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public static void main(String[] args) { String fileName = "person.ser"; writeObjectToFile(fileName); readObjectFromFile(fileName); } private static void writeObjectToFile(String fileName) { try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(fileName))) { Person person = new Person("Alice", 30); outputStream.writeObject(person); System.out.println("Object written to file successfully."); } catch (IOException e) { e.printStackTrace(); } } private static void readObjectFromFile(String fileName) { try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName))) { Object obj = inputStream.readObject(); if (obj instanceof Person) { Person person = (Person) obj; System.out.println("Object read from file: " + person); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
在上面的示例中,Person
类实现了 ObjectInputValidation
接口,并重写了 validateObject()
方法来验证对象的有效性。在 validateObject()
方法中,我们检查年龄是否为负数,如果是,则抛出 InvalidObjectException
。在 main
方法中,我们先将一个 Person
对象写入文件,然后再从文件中读取该对象。由于 Person
类实现了 ObjectInputValidation
接口,因此在读取对象时会自动调用其 validateObject()
方法来验证对象的有效性。
应用场景
ObjectInputValidation
接口通常用于在反序列化对象时执行一些验证操作,以确保反序列化的对象的完整性和有效性。以下是一些可能的应用场景及相应的代码实现:
应用场景 1: 验证对象的版本信息
javaCopy code import java.io.*; public class VersionedObject implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 1L; private int version; public VersionedObject(int version) { this.version = version; } @Override public void validateObject() throws InvalidObjectException { if (version != 1) { throw new InvalidObjectException("Invalid object version: " + version); } } }
应用场景 2: 验证对象的某些属性是否有效
javaCopy code import java.io.*; public class ValidatedObject implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 1L; private String name; private int age; public ValidatedObject(String name, int age) { this.name = name; this.age = age; } @Override public void validateObject() throws InvalidObjectException { if (age < 0 || age > 120) { throw new InvalidObjectException("Invalid age: " + age); } if (name == null || name.trim().isEmpty()) { throw new InvalidObjectException("Name cannot be null or empty"); } } }
应用场景 3: 对象签名验证
javaCopy code import java.io.*; public class SignedObject implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 1L; private String data; private String signature; public SignedObject(String data, String signature) { this.data = data; this.signature = signature; } @Override public void validateObject() throws InvalidObjectException { // 在此处验证签名是否有效 if (!verifySignature(data, signature)) { throw new InvalidObjectException("Invalid signature"); } } private boolean verifySignature(String data, String signature) { // 实现签名验证逻辑 return true; // 假设此处为验证通过 } }
应用场景 4: 对象完整性验证
javaCopy code import java.io.*; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class IntegrityCheckedObject implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 1L; private String data; private String checksum; public IntegrityCheckedObject(String data, String checksum) { this.data = data; this.checksum = checksum; } @Override public void validateObject() throws InvalidObjectException { if (!verifyChecksum(data, checksum)) { throw new InvalidObjectException("Data integrity check failed"); } } private boolean verifyChecksum(String data, String checksum) { // 计算数据的校验和并与提供的校验和进行比较 try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(data.getBytes()); String computedChecksum = bytesToHex(digest); return computedChecksum.equals(checksum); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return false; } } private static String bytesToHex(byte[] bytes) { StringBuilder result = new StringBuilder(); for (byte b : bytes) { result.append(String.format("%02x", b)); } return result.toString(); } }
以上是一些使用 ObjectInputValidation
接口的应用场景和相应的代码实现。这些场景涵盖了从简单的对象属性验证到更复杂的对象签名和完整性验证。
实战例子
以下是一个项目实战例子,演示了如何在对象序列化和反序列化时使用 ObjectInputValidation
接口来验证对象的有效性:
javaCopy code import java.io.*; public class ObjectValidationExample { static class User implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 1L; private String username; private transient String password; // 密码字段不参与序列化 public User(String username, String password) { this.username = username; this.password = password; } @Override public void validateObject() throws InvalidObjectException { if (username == null || username.isEmpty()) { throw new InvalidObjectException("Username cannot be null or empty"); } if (password == null || password.isEmpty()) { throw new InvalidObjectException("Password cannot be null or empty"); } } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + '}'; } } public static void main(String[] args) { String fileName = "user.ser"; // 写入对象到文件 writeObjectToFile(fileName); // 从文件读取对象并处理 readObjectFromFile(fileName); } private static void writeObjectToFile(String fileName) { try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(fileName))) { User user = new User("john.doe", "password123"); outputStream.writeObject(user); System.out.println("Object written to file successfully."); } catch (IOException e) { e.printStackTrace(); } } private static void readObjectFromFile(String fileName) { try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName))) { Object obj = inputStream.readObject(); if (obj instanceof User) { User user = (User) obj; System.out.println("Object read from file: " + user); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }
在这个例子中,我们定义了一个 User
类,该类实现了 Serializable
接口和 ObjectInputValidation
接口。在 User
类中,我们定义了两个字段 username
和 password
,并在 validateObject()
方法中验证了这两个字段的有效性。在 main
方法中,我们首先将一个 User
对象写入文件,然后再从文件中读取该对象。在读取对象时,validateObject()
方法会被自动调用来验证对象的有效性。