简体   繁体   English

如何将字符串反序列化为Java对象

[英]How to Deserialize String to Java Object

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. 我尝试从用于存储Spring会话的Redis服务器将String反序列化为Java Object,我想在Spring框架之外对它反序列化。 I think the Spring Redis serializer is probably using the default charset, UTF-8, to serialize Java Object to String. 我认为Spring Redis序列化程序可能正在使用默认字符集UTF-8将Java Object序列化为String。

The String in Redis: 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 \\ xAC \\ xED \\ x00 \\ x05sr \\ x00 \\ x0Ejava.lang.Long; \\ x8B \\ xE4 \\ x90 \\ xCC \\ x8F#\\ xDF \\ x02 \\ x00 \\ x01Jx \\ 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. 我知道用UTF-8在byte []和String之间进行转换可能是问题所在,但我仍然想问是否有人知道如何解决此问题而不修改序列化部分。

I would suggest you parse the string yourself. 我建议您自己解析该字符串。 It looks like it's a simple sequence of escaped and unescaped bytes. 看起来这是转义和未转义字节的简单序列。

String value = "\\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";

try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
    int i = 0;
    while (i < value.length()) {
        char ch = value.charAt(i);
        if (ch == '\\') {
            if (value.charAt(i + 1) != 'x') {
                throw new UnsupportedOperationException();
            }
            String hex = value.substring(i + 2, i + 4);
            byteArrayOutputStream.write(Integer.parseInt(hex, 16) & 0xFF);
            i += 4;
        } else {
            byteArrayOutputStream.write(ch);
            i++;
        }
    }

    byte[] output = byteArrayOutputStream.toByteArray();
    Long id = (Long) deserialize(output);
    System.out.println(id);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM