Converting from object to byte array and back in java

12,526

Solution 1

This should work, just cast the object to your class after receiving it from the serialize/deserialize function.

public static byte[] objToByte(TcpPacket tcpPacket) throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
    objStream.writeObject(tcpPacket);

    return byteStream.toByteArray();
}

public static Object byteToObj(byte[] bytes) throws IOException, ClassNotFoundException {
    ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
    ObjectInputStream objStream = new ObjectInputStream(byteStream);

    return objStream.readObject();
}

Solution 2

I'd like to offer you the manual approach to serialising your class.

public static final class TcpPacket {

    public byte [] toByteArray() {
        ByteBuffer b = ByteBuffer.allocate(4 * 2);
        return b.putInt(source).putInt(destination).array();
    }

    public static TcpPacket fromByteArray(byte [] bytes) {
        if (bytes.length < 8) throw new IllegalArgumentException("not enough bytes");

        ByteBuffer b = ByteBuffer.wrap(bytes);
        int source = b.getInt();
        int destination = b.getInt();
        return new TcpPacket(source, destination);
    }
}

Adding a toByteArray and static fromByteArray methods would get you what you want and has the following benefits:

  • Very small representation, only 8 bytes, could in theory be smaller with variable length encoding of the integers
  • Doesn't expose your application to Java serialisation security issues, as clearly you are going to be deserialising data from a network connection.

If you require a serializing more complex data structures I would very strongly recommend you choose a well established serialization library such as google protocol buffers (my personal weapon of choice) or one of the many others that don't suffer from the security nightmare that is Java serialization.

Share:
12,526
Maricruzz
Author by

Maricruzz

Updated on June 25, 2022

Comments

  • Maricruzz
    Maricruzz almost 2 years

    I have two classes: TcpPacket and IpPacket. The tcpPacket should be stored in the data field of the ip packet. How can I reliably convert the tcpPacket object to a byte array so that i can store it in the IpPacket's data field? And upon receiving the packet on the other side, how to reliably convert it back into a packet object?

    public static final class TcpPacket {
        int source;
        int destination;
    
        public Packet( int source, int destination ) {
            this.source = source;
            this.destination = destination;
        }
    
        public String toString() {
            return "Source: " + source + ", Dest: " + destination;
        }
    }
    
    public static final class IpPacket {
        byte[] data;
    
        IpPacket( byte[] data ){
            this.data = data;
        }
    }
    
    TcpPacket tcpPacket = new TcpPacket( <someint>, <someint> );
    
    // the following doesn't work because tcppacket is not a byte array.
    IpPacket ipPacket = new IpPacket( tcpPacket );
    

    How is this usually done?

    Thanks Maricruzz