我在redis中存储了一个用messagepack打包的lua表,如何获取它并用java解压缩?

时间:2014-08-16 17:50:52

标签: java lua redis msgpack

下面的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);

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

1 个答案:

答案 0 :(得分:1)

问题可能是您正在使用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