文档章节

让java版msgpack支持Object类型

pigsoldier
 pigsoldier
发布于 2014/06/10 02:16
字数 757
阅读 4124
收藏 8

msgpack是一种高效的二进制序列化格式,官方链接提供了很多中语言的实现,Java作为常用的开发语言之一,官方也提供了支持。</br>

Java版的实现官方也提供了一些QuickStart教程,这里就不多说了,主要说下之前遇到的一个问题,由于某个POJO对象里含有Map<Integer, Object>类型的成员,在使用msgpack进行序列化和反序列化时,出现了一些奇怪的现象,比如反序列化出来的Map在进行get时无法表现出正常的操作,虽然Debug时看到内存里确实有数据。后来简单分析了一下发现,在没有指定模板类型时,msgpack反序列化出来的Map实际上是其Jar包内自己封装的一个Map实现类,所以就会出现上述的情况,要解决这个问题,就需要在反序列化解析时,给msgpack明确指定模板类型。

msgpack的内置提供了很多模板,其中就有MapTemplate,这是一个泛型类,在构造时需要指定key和val的模板类型,而msgpack并没有内置Object的模板,所以当如果需要序列化和反序列化一个Value是Object的Map时,就会出现问题。因此我们需要自己来实现一个Object的模板,代码如下:

public class ObjectTemplate extends AbstractTemplate<Object> {

private ObjectTemplate() {
}

static public ObjectTemplate getInstance() {
    return instance;
}

static final ObjectTemplate instance = new ObjectTemplate();

@Override
public void write(Packer pk, Object v, boolean required) throws IOException {
    if (v == null) {
        if (required) {
            throw new MessageTypeException("Attempted to write null");
        }
        pk.writeNil();
        return;
    }
    pk.write(v);
}

@Override
public Object read(Unpacker u, Object to, boolean required) throws IOException {
    if (!required && u.trySkipNil()) {
        return null;
    }

    return toObject(u.readValue());
}

private static Object toObject(Value value) throws IOException {
    Converter conv = new Converter(value);
    if (value.isNilValue()) { // null
        return null;
    } else if (value.isRawValue()) { // byte[] or String or maybe Date?
        // deserialize value to String object
        RawValue v = value.asRawValue();
        return conv.read(Templates.TString);
    } else if (value.isBooleanValue()) { // boolean
        return conv.read(Templates.TBoolean);
    } else if (value.isIntegerValue()) { // int or long or BigInteger
        // deserialize value to int
        IntegerValue v = value.asIntegerValue();
        return conv.read(Templates.TInteger);
    } else if (value.isFloatValue()) { // float or double
        // deserialize value to double
        FloatValue v = value.asFloatValue();
        return conv.read(Templates.TDouble);
    } else if (value.isArrayValue()) { // List or Set
        // deserialize value to List object
        ArrayValue v = value.asArrayValue();
        List<Object> ret = new ArrayList<Object>(v.size());
        for (Value elementValue : v) {
            ret.add(toObject(elementValue));
        }
        return ret;
    } else if (value.isMapValue()) { // Map
        MapValue v = value.asMapValue();


        Map map = new HashMap<>(v.size());
        for (Map.Entry<Value, Value> entry : v.entrySet()) {
            Value key = entry.getKey();
            Value val = entry.getValue();

            map.put(toObject(key), toObject(val));
        }

        return map;
    } else {
        throw new RuntimeException("fatal error");
    }
}
}

以上代码在issue4的基础上增加了支持基本类型作为K-V的Map的嵌套,我测试了三层嵌套Map是可以的,更深层的没有去测试,不过一般使用也应该够用了。以上模板在使用msgpack进行read和write时作为参数传递进去即可,如下面的例子 :

        MessagePack pack = new MessagePack();
        byte[] bytes = pack.write(map);
        Map<Integer, Object> m = pack.read(bytes, Templates.tMap(Templates.TInteger, ObjectTemplate.getInstance()));

总体来说msgpack还是很好用的,所以在当我们用一个开源项目遇到问题时,先最好多看看文档和源码,很多时候就能解决我们遇到的问题,而不是过多的抱怨

© 著作权归作者所有

共有 人打赏支持
pigsoldier
粉丝 5
博文 18
码字总数 8790
作品 0
海淀
程序员
加载中

评论(1)

沙漠中的蒲公英
List<Object>类型的怎么搞
golang and java msgpack 不同

用golang 写了个server,java写了个client 通讯使用msgpack 进行打包,发现golang和java pack的包不一致 public class MyMessage { // public fields are serialized. public String name; ......

咖啡伴侣
2014/02/26
0
1
用 JNI 进行 Java 编程(5)

结束语和参考资料 结束语 Java 本机接口是 Java 平台中一种设计良好和良好集成的 API。它被设计成用来使您能将本机代码合并到 Java 程序中,也为您提供了一种在用其它编程语言编写的程序中使...

Jerikc
2012/10/08
0
0
asm学习2-java类在asm里的基本描述

上节里有关于asm的一些基本概念,比如:visit里的第一个类版本,方法的描述、引用描述等,下面将一一介绍。 类版本 一个Java二进制的类文件,都有一个版本,对应于不同的jdk版本。因此ASM中提...

messud4312
2015/02/06
0
0
java类ThreadLocal的理解

ThreadLocal是什么 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更...

保罗的寓言
2011/05/21
0
1
从java1到java9每个版本都有什么新特性?五分钟了解

     其实,我是个标题党,没有java1的说法,java9的新特性我也没总结。所以,来个关注吧,说不定哪天就出了呢。。。   每次出新版本,大家大概都会这么问,“Java X会有什么特性呢?”...

java进阶架构师
2017/11/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

go语言学习总结

一、描述 go语言是直接将源码编译成二进制机器码的语言;它支持面向对象、也支持函数式编程;支持并发很容易; 二、基本语法学习路径 https://studygolang.com/subject/2...

盼望明天
17分钟前
1
0
JSP 九大内置对象及其作用域

JSP 中一共预先定义了 9 个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception ,下面就简单介绍下。 1、request 对象 request 对象...

几个栗子
28分钟前
0
0
Java中的坑之方括号

Java中的坑之方括号 这一段时间,在做项目的时候,发现了一个坑,这个坑说大不大,说小不小,不知道的足够喝一壶,知道的就可以轻松解决。 问题描述 在做数据统计的时候,遇见了如下形式的数...

星汉
38分钟前
1
0
[雪峰磁针石博客]python机器学习、web开发等书籍汇总

Building Machine Learning Systems with Python Third Edition - 2018.pdf 下载地址 Get more from your data by creating practical machine learning systems with Python Key Features ......

python测试开发人工智能安全
49分钟前
1
0
文件的压缩与解压(linux)

Linux下*.tar.gz文件解压缩命令 1.压缩命令:   命令格式:tar -zcvf 压缩后文件名.tar.gz 被压缩文件名 可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令: ...

qimh
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部