Class ValidatingObjectInputStream

java.lang.Object
java.io.InputStream
java.io.ObjectInputStream
org.apache.commons.io.serialization.ValidatingObjectInputStream
All Implemented Interfaces:
Closeable, DataInput, ObjectInput, ObjectStreamConstants, AutoCloseable

An ObjectInputStream that's restricted to deserialize a limited set of classes.

Various accept/reject methods allow for specifying which classes can be deserialized.

Reading safely

Here is the only way to safely read a HashMap of String keys and Integer values:

// Defining Object fixture
final HashMap<String, Integer> map1 = new HashMap<>();
map1.put("1", 1);
// Writing serialized fixture
final byte[] byteArray;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final ObjectOutputStream oos = new ObjectOutputStream(baos)) {
    oos.writeObject(map1);
    oos.flush();
    byteArray = baos.toByteArray();
}
// Reading
try (ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
        ValidatingObjectInputStream vois = ValidatingObjectInputStream.builder()
            .accept(HashMap.class, Number.class, Integer.class)
            .setInputStream(bais)
            .get()) {
    // String.class is automatically accepted
    final HashMap<String, Integer> map2 = (HashMap<String, Integer>) vois.readObject();
    assertEquals(map1, map2);
}
// Reusing a configuration
final ObjectStreamClassPredicate predicate = new ObjectStreamClassPredicate()
    .accept(HashMap.class, Number.class, Integer.class);
try (ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
        ValidatingObjectInputStream vois = ValidatingObjectInputStream.builder()
            .setPredicate(predicate)
            .setInputStream(bais)
            .get()) {
    // String.class is automatically accepted
    final HashMap<String, Integer> map2 = (HashMap<String, Integer>) vois.readObject();
    assertEquals(map1, map2);
}

Design inspired by a IBM DeveloperWorks Article.

Since:
2.5