I try to deserialize String to Java Object from a Redis server which is used to store Spring sessions, and I want to deserialize it outside of the Spring framework. I think the Spring Redis serializer is probably using the default charset, UTF-8, to serialize Java Object to String.
The String in Redis:
\xAC\xED\x00\x05sr\x00\x0Ejava.lang.Long;\x8B\xE4\x90\xCC\x8F#\xDF\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xAC\x95\x1D\x0B\x94\xE0\x8B\x02\x00\x00xp\x00\x00\x00\x00\x00\x00\xD7
The method I use:
private static void scanKeys(Jedis jedis, String prefix, String hashKey)
throws IOException, ClassNotFoundException {
Set<String> keys = jedis.keys(prefix + "*");
for (String key : keys) {
if (!key.contains("expir")) {
Map<String, String> sessionMap = jedis.hgetAll(key);
for (Entry<String, String> entry : sessionMap.entrySet()) {
if (entry.getValue() != null && entry.getKey().equals(hashKey)) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
byte[] output = entry.getValue().getBytes(charset);
System.out.println(Arrays.toString(output));
try {
Long id = (Long) deserialize(output);
System.out.println(id);
} catch (EOFException e) {
break;
}
}
}
}
}
}
public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is = new ObjectInputStream(in);
return is.readObject();
}
The error message:
java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:862)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:354)
at practice.redis.jedis.App.deserialize(App.java:191)
at practice.redis.jedis.App.scanKeys(App.java:168)
at practice.redis.jedis.App.main(App.java:77)
I know the conversion between byte[] and String with UTF-8 is probably where the problem is, but I still want to ask if anyone knows how to solve this problem without modifying the serialization part.