Implementing a custom method ObjectInputFilter – Java I/O: Context-Specific Deserialization Filters


130. Implementing a custom method ObjectInputFilter

Let’s assume that we already have the Melon class and the helper methods for serializing/deserializing objects to/from byte arrays from Problem 124.An ObjectInputFilter can be written via a dedicated method as in the following example:

public final class Filters {
 private Filters() {
  throw new AssertionError(“Cannot be instantiated”);
 }
 public static ObjectInputFilter.Status melonFilter(
               FilterInfo info) {
  Class<?> clazz = info.serialClass();
  if (clazz != null) {
   // or, clazz.getName().equals(“modern.challenge.Melon”)
   return
    !(clazz.getPackage().getName().equals(“modern.challenge”)
      && clazz.getSimpleName().equals(“Melon”))
      ? Status.ALLOWED : Status.REJECTED;
   }
   return Status.UNDECIDED;
 }
}

Of course, you can add more filters in this class.We can set this filter as a stream-global filter as follows:

ObjectInputFilter.Config
                 .setSerialFilter(Filters::melonFilter);

Or, as a stream-specific filter as follows:

Melon melonDeser = (Melon) Converters.bytesToObject(
  melonSer, Filters::melonFilter);

Of course, the bytesToObject() accepts an argument of type ObjectInputFilter and sets this filter accordingly (ois is the specific ObjectInputStream):

ois.setObjectInputFilter(filter);

In this example, the Filters::melonFilter will reject deserialization and the output will be as follows:

Exception in thread “main” java.io.InvalidClassException: filter status: REJECTED

You can check out both approaches (stream-global and stream-specific) in the bundled code. Moreover, you can also practice another example that rejects all instances of Melon and its subclasses based on a stream-global filter.

131. Implementing a custom lambda ObjectInputFilter

Let’s assume that we already have the Melon class and the helper methods for serializing/deserializing objects to/from byte arrays from Problem 124.An ObjectInputFilter can be written via a dedicated lambda and set it as a stream-global filter as follows:

ObjectInputFilter.Config
  .setSerialFilter(f -> ((f.serialClass() != null)
  // or, filter.serialClass().getName().equals(
  //     “modern.challenge.Melon”)
  && f.serialClass().getPackage()
                    .getName().equals(“modern.challenge”)
  && f.serialClass().getSimpleName().equals(“Melon”))
  ? Status.REJECTED : Status.UNDECIDED);

Or, as a stream-specific filter as follows:

Melon melonDeser = (Melon) Converters.bytesToObject(melonSer,
  f -> ((f.serialClass() != null)
   // or, filter.serialClass().getName().equals(
          “modern.challenge.Melon”)
   && f.serialClass().getPackage()
                     .getName().equals(“modern.challenge”)
   && f.serialClass().getSimpleName().equals(“Melon”))
   ? Status.REJECTED : Status.UNDECIDED);

You can practice these examples in the bundled code.

Leave a Reply

Your email address will not be published. Required fields are marked *