Serialize an object to a String

In Core J2EE Design Patterns 2nd edition, I saw a small hack that I wasn’t aware of. You can serialize/deserialize any Serializable object to/from a String. I saw this in the Service Locator design pattern where it is used to serialize/deserialize javax.ejb.Handle objects (pages 332-333).

The above serialization is very easy to implement. All you need is to:

  1. Construct an ObjectOutputStream from a ByteArrayOutputStream
  2. Serialize to Object calling writeObject() on the ObjectOutputStream
  3. Construct a String from the bytes of the ByteArrayOutputStream

Below I have implemented, in Java 5, a class that serializes/deserializes any Serializable object to/from a String object.

import java.io.*;

public class ToStringSerializer<T extends Serializable> {

  public String serialize(T t) throws IOException {
    ByteArrayOutputStream bs = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(bs);
    os.writeObject(t);
    return new String(bs.toByteArray());
  }

  public T fromString(String s) throws IOException, ClassNotFoundException {
    ByteArrayInputStream bs = new ByteArrayInputStream(s.getBytes());
    ObjectInputStream os = new ObjectInputStream(bs);
    return (T) os.readObject();
  }
}

A minimal unit test to demonstrate the usage of the above class:

import java.io.Serializable;
import junit.framework.TestCase;

public class ToStringSerializerTest extends TestCase {

  public final void testSerialize() throws Exception {
    Pair<String , String> p = new Pair<String, String>("Fist", "Second");
    ToStringSerializer<Pair<String, String>> serializer =
      new ToStringSerializer<Pair<String, String>>();
     
     String pAsString = serializer.serialize(p);
     Pair<String, String> newP = serializer.fromString(pAsString);
     assertEquals(p, newP);
  }

  static class Pair<F, S> implements Serializable {

    private F first;
    private S second;

    public Pair(F f, S s) { first = f; second = s; }

    public Pair() {}

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof Pair)) return false;
        Pair p = (Pair) obj;
          return first.equals(p.first) && second.equals(p.second);
    }

    @Override
    public int hashCode() {
      return 71*first.hashCode() + second.hashCode();
    }
  }
}