我将一个使用MessagePack打包好的Lua表存储在Redis中,如何使用Java获取并解包它?

Redis lua 脚本:

local vv = cmsgpack.unpack(msgpack)
local mv = {[\"v\"]=v, [\"t\"]=t, [\"tp\"]=tp, [\"pt\"] = pt}
table.insert(vv, mv)
msgpack = cmsgpack.pack(vv)

我使用 Java 从表格中读取:

@Message
public static class UserMessage {
  public String v;
  public long t;
  public String tp;
  public String pt;
}

String ret = redisClient.hget(uid, "m:v");
byte[] bytes = ret.getBytes();
MessagePack msgpack = new MessagePack();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
Unpacker unpacker = msgpack.createUnpacker(in);
UserMessage[] dst = unpacker.read(UserMessage[].class);

但是它是错误的,无法正确解包,我不知道哪里出错了? 这让我困扰了很长时间...

点赞
用户2759336
用户2759336

问题可能是您正在使用String对象来获取HGET的结果。您需要一个byte []。String对象会执行各种令人讨厌的操作,例如解释代码页、空字符等。即使它起作用,这也是很多额外工作。因此,请使用byte [],我猜您的redis客户端有一种方法可以做到这一点。

我们使用aredis从Redis检索msgpack数据。以下是一些线索:

import org.aredis.cache.AsyncRedisClient;
import org.aredis.cache.AsyncRedisFactory;
import org.aredis.cache.DataHandler;
import org.aredis.cache.RedisCommand;
import org.aredis.cache.RedisCommandInfo;
import org.aredis.io.CompressibleByteArrayOutputStream;
import org.aredis.net.ServerInfo;

private class RawHandler extends Object implements DataHandler {

  @Override
  public Object deserialize(Object arg0, byte[] arg1, int arg2, int arg3, ServerInfo arg4) throws IOException {
    return arg1;
  }

  @Override
  public void serialize(Object arg0, Object arg1, CompressibleByteArrayOutputStream arg2, ServerInfo arg3) throws IOException {
    throw new NotActiveException("Not supported, deserialize only.");
  }

}

Future<RedisCommandInfo> futureOE = oRedis.oCliDpart.submitCommand(
    new RawHandler(),
    RedisCommand.ZRANGEBYLEX,
    "_ourkey#blabla.d",
    String.format("[%s;", cDbAndTable),
    String.format("(%s<", cDbAndTable));
  ...

  final Object[] val = (Object[]) futureOE.get().getResult();
  for (Object item : val) {
    if (item instanceof byte[]) {
    ...

从那里开始,msgpack反序列化应该很容易。

希望这能有所帮助,TW

2014-08-16 20:15:52