Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Java - ObjectInputStream readStreamHeader() method



Description

The Java ObjectInputStream readStreamHeader() method is a protected method used to read and validate the stream header during deserialization. It is typically overridden in subclasses of ObjectInputStream to customize how stream headers are processed.

Declaration

Following is the declaration for java.io.ObjectInputStream.readStreamHeader() method −

public void readStreamHeader()

Parameters

NA

Return Value

This method returns the 16 bit short read.

Exception

  • StreamCorruptedException − If control information in the stream is inconsistent.

  • IOException − If there are I/O errors while reading from the underlying InputStream.

Example - Logging When Reading Stream Header

The following example shows the usage of Java ObjectInputStream readStreamHeader() method. This example overrides readStreamHeader() to log a message whenever an object stream is read.

ObjectInputStreamDemo.java

package com.tutorialspoint;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectInputStreamDemo {
   public static void main(String[] args) {

      String filename = "data.ser";

      // Writing an object to a file
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
         oos.writeObject("Hello, World!");
         System.out.println("Object written to file.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Reading the object using CustomObjectInputStream
      try (CustomObjectInputStream cois = new CustomObjectInputStream(new FileInputStream(filename))) {
         String message = (String) cois.readObject();
         System.out.println("Read object: " + message);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }

   static class CustomObjectInputStream extends ObjectInputStream {
      public CustomObjectInputStream(InputStream in) throws IOException {
         super(in);
      }

      @Override
      protected void readStreamHeader() throws IOException {
         System.out.println("Custom stream header is being read...");
         super.readStreamHeader(); // Call the default header reading
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Object written to file.
Custom stream header is being read...
Read object: Hello, World!

Explanation

  • CustomObjectInputStream overrides readStreamHeader() to print a log message.

  • It then calls super.readStreamHeader() to ensure the header is correctly read.

  • An object is written and read using this custom stream, with a log message appearing when reading.

Example - Validating a Custom Header

The following example shows the usage of Java ObjectInputStream readStreamHeader() method. This example writes a custom stream header before serializing objects and ensures it is correctly validated when deserializing.

ObjectInputStreamDemo.java

package com.tutorialspoint;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class ObjectInputStreamDemo{
   public static void main(String[] args) {
      String filename = "customHeaderData.ser";
      // Writing object with custom header
      try (CustomHeaderObjectOutputStream oos = new CustomHeaderObjectOutputStream(new FileOutputStream(filename))) {
         oos.writeObject("Test Message");
         System.out.println("Object written with custom header.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Reading object with custom header validation
      try (CustomHeaderObjectInputStream ois = new CustomHeaderObjectInputStream(new FileInputStream(filename))) {
         String message = (String) ois.readObject();
         System.out.println("Read object: " + message);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }

   static class CustomHeaderObjectInputStream extends ObjectInputStream {
      public CustomHeaderObjectInputStream(InputStream in) throws IOException {
         super(in);
      }

      @Override
      protected void readStreamHeader() throws IOException {
         int header = readInt();
         if (header != 123456) {
            throw new IOException("Invalid stream header!");
         }
         System.out.println("Custom stream header validated.");
      }
   }

   static class CustomHeaderObjectOutputStream extends ObjectOutputStream {
      public CustomHeaderObjectOutputStream(OutputStream out) throws IOException {
         super(out);
      }

      @Override
      protected void writeStreamHeader() throws IOException {
         writeInt(123456); // Writing a custom header instead of the default one
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Object written with custom header.
Custom stream header validated.
Read object: Test Message

Explanation

  • Custom header writingCustomHeaderObjectOutputStream writes an integer (123456) as a custom stream header.

  • Custom header readingCustomHeaderObjectInputStream reads the integer and validates it before proceeding.

  • If the header does not match 123456, an exception is thrown.

Example - Preventing Deserialization of Untrusted Streams

The following example shows the usage of Java ObjectInputStream readStreamHeader() method. This example overrides readStreamHeader() to log a message whenever an object stream is read.

ObjectInputStreamDemo.java

package com.tutorialspoint;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class ObjectInputStreamDemo {
   public static void main(String[] args) {

      String filename = "secureData.ser";

      // Writing an object with a secure header
      try (SecureObjectOutputStream oos = new SecureObjectOutputStream(new FileOutputStream(filename))) {
         oos.writeObject("Secure Message");
         System.out.println("Object written with secure header.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      // Reading the object with secure header validation
      try (SecureObjectInputStream ois = new SecureObjectInputStream(new FileInputStream(filename))) {
         String message = (String) ois.readObject();
         System.out.println("Read secure object: " + message);
      } catch (IOException | ClassNotFoundException e) {
         e.printStackTrace();
      }
   }

   static class SecureObjectInputStream extends ObjectInputStream {
      public SecureObjectInputStream(InputStream in) throws IOException {
         super(in);
      }

      @Override
      protected void readStreamHeader() throws IOException {
         int magic = readInt();
         int version = readInt();

         if (magic != 0xCAFEBABE || version != 1) {
            throw new IOException("Untrusted data stream!");
         }
         System.out.println("Secure stream header validated.");
      }
   }

   static class SecureObjectOutputStream extends ObjectOutputStream {
      public SecureObjectOutputStream(OutputStream out) throws IOException {
         super(out);
      }

      @Override
      protected void writeStreamHeader() throws IOException {
         writeInt(0xCAFEBABE); // Magic number
         writeInt(1); // Version number
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Object written with secure header.
Secure stream header validated.
Read secure object: Secure Message

Explanation

  • Custom security headersSecureObjectOutputStream writes a magic number (0xCAFEBABE) and a version number (1).

  • Validation during deserializationSecureObjectInputStream reads and validates these values before allowing deserialization. If the header doesn't match, deserialization is blocked.

java_io_objectinputstream.htm
Advertisements