2

I'm trying to serialize and object, parse to String and deserialize, but it doesn't work. I guess I'm missing something when I parse the byte[] to String or viceversa.

String obj = new String(SerializationUtils.serialize(configuration));
Configuration test = (Configuration)SerializationUtils.deserialize(obj.getBytes());

Why doesn't it work?

I get this error:

org.apache.commons.lang.SerializationException: java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
    at org.apache.commons.lang.SerializationUtils.deserialize(SerializationUtils.java:168)
    at org.apache.commons.lang.SerializationUtils.deserialize(SerializationUtils.java:193)

Solution:

There're to encode and decote the byte[] to Base64

5
  • What error are you getting? Where's the problem? And why are you storing the serialized data in a String? It's a byte[]. Commented May 13, 2014 at 7:38
  • I added some information. Commented May 13, 2014 at 7:43
  • I added because I have to send the configuration other system and they just admit String,, arggg. Commented May 13, 2014 at 7:45
  • 1
    If it is binary array you must encode it to BASE64 first and the decode it back from BASE64 string to byte array. Copying bytes to String may lead to loss of data. Commented May 13, 2014 at 7:46
  • Ok, so I will not write a code sample. Commented May 13, 2014 at 7:51

3 Answers 3

5

After you added the information, this is easy to answer.

The serialized data is a byte array, yet you wrap in in a String object. The String object does it's own magic - in this case the UTF8-Charset is used.

UTF8 has something like a BOM ("Byte Order Mark") which is used as an internal header of the String object. This BOM (which consists of the data EF BB BF, it is defined that as that. Note that it's the very same data from your exception!) is part of the String's bytes (the first 3 bytes to be exact). That messes up the deserialization because for the deserialize method, those 3 byte are garbage.

That is why you get the exception.

I strongly advise against using String as a container for raw binary data such as your serialized byte[].

Since you said that the remote system only allows String, try to create create your String with a different charset that is not UTF8 or find a way to disable the BOM.

Sign up to request clarification or add additional context in comments.

4 Comments

As I commented, he shall encode binary stream to BASE64. This is the safe solution, not proposing other charset.
It's not a solution. In the comments he stated that the remote system where he wants to send the serialized data to only accepts a String. Encoding the data in base64 would require the remote system (which he has no access to) to decode the base64 data. Since he can't do that he has to write the raw data.
I hope that he can convince them to accept BASE64 string.
They accept Base64, it's okay that solution. Thanks everybody.
1

However it is not a good idea to store sensitive data in Strings here is the code which will do the job:

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import org.apache.commons.lang.SerializationUtils;

    public class Serializer {
        public static String SerializeToString(Serializable input) throws UnsupportedEncodingException{
            byte [] repr = SerializationUtils.serialize(input);
            String decoded = new String(repr,"ISO-8859-1");
            return decoded;
        }

        public static Object DeserializeFromString(String input) throws UnsupportedEncodingException{
            byte [] repr = input.getBytes("ISO-8859-1");
            return SerializationUtils.deserialize(repr);
        }
    }

Comments

1

Another way would be to de- and encode the byte array with java.lang.Base64 to base64 and store / read this value.

Example Code:

byte[] input = SerializationUtils.serialize(yourObject);
String encodedInput = Base64.getEncoder().encodeToString(input);

byte[] decodedOutput = Base64.getDecoder().decode(encodedInput);
Object output = SerializationUtils.deserialize(decodedOutput);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.