It's like JSON.
but fast and small.
这句话是官网对他的评价,它像json,但是更快,更小。
msgpack目前已经更新到了0.8.x。和老版本的6.x有很大的区别,6.x与(7.x和8.x)之间进行序列化的数据也将相互不通用。
6.x与(7.x和8.x)之间也更改了名字,6.x是msgpack,而7.x与8.x是msgpack-core
msgpack是将数据序列化成二进制数据。
本文所有jar包使用:
<!-- https://mvnrepository.com/artifact/org.msgpack/msgpack-core --> <dependency> <groupId>org.msgpack</groupId> <artifactId>msgpack-core</artifactId> <version>0.8.13</version> </dependency> <!-- https://mvnrepository.com/artifact/org.msgpack/jackson-dataformat-msgpack --> <dependency> <groupId>org.msgpack</groupId> <artifactId>jackson-dataformat-msgpack</artifactId> <version>0.8.13</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.7.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.7.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.35</version> </dependency>
简单介绍一下msgpack-core对java对象的序列化和反序列化。
官网中提供了一个jackson-dataformat-msgpack的包,利用jackson来封装序列化和反序列化java对象。
创建测试实体类:Person.java
package com.againfly.msgpack; public class Person { private String name; private int age; private boolean sex; public Person() { } public Person(String name, int age, boolean sex) { this.name = name; this.age = age; this.sex = sex; } /****省略get,set方法*****/ @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
实体对象转byte[]
Person person = new Person("Jecced", 18, true); ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); byte[] bytes = mapper.writeValueAsBytes(person); System.out.println(bytes.length); System.out.println(Arrays.toString(bytes));
23 [-125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101, 18, -93, 115, 101, 120, -61]
byte[]转实体对象
ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); byte[] bytes = { -125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101, 18, -93, 115, 101, 120, -61 }; Person person = mapper.readValue(bytes, Person.class); System.out.println(person);
Person [name=Jecced, age=18, sex=true]
byte[]转集合对象
List<Person> list = new ArrayList<Person>(); list.add(new Person("Jecced", 18, true)); list.add(new Person("Ruby", 3, false)); ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); byte[] bytes = mapper.writeValueAsBytes(list); System.out.println(bytes.length); System.out.println(Arrays.toString(bytes)); System.out.println("======================="); JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, Person.class); List<Person> list2 = mapper.readValue(bytes, javaType); System.out.println(list2);
45 [-110, -125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101, 18, -93, 115, 101, 120, -61, -125, -92, 110, 97, 109, 101, -92, 82, 117, 98, 121, -93, 97, 103, 101, 3, -93, 115, 101, 120, -62] ======================= [Person [name=Jecced, age=18, sex=true], Person [name=Ruby, age=3, sex=false]]
简单封装一下:MsgPackUtil.java
package com.againfly.msgpack; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.msgpack.jackson.dataformat.MessagePackFactory; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; public class MsgPackUtil { private static ObjectMapper mapper = new ObjectMapper(new MessagePackFactory()); /** * @Title: toBytes * @Description: 对象转byte数组 * @author Jecced * @param obj * @return */ public static <T> byte[] toBytes(T obj) { try { return mapper.writeValueAsBytes(obj); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * @Title: toList * @Description: byte转list集合 * @author Jecced * @param bytes * @param clazz * @return */ public static <T> List<T> toList(byte[] bytes, Class<T> clazz) { List<T> list = null; try { list = mapper.readValue(bytes, MsgPackUtil.List(clazz)); } catch (IOException e) { list = new ArrayList<>(); e.printStackTrace(); } return list; } /** * @Title: toObject * @Description: byte转指定对象 * @author Jecced * @param bytes * @param clazz * @return */ public static <T> T toObject(byte[] bytes, Class<T> clazz) { T value = null; try { value = mapper.readValue(bytes, clazz); } catch (IOException e) { e.printStackTrace(); } return value; } /** * @Title: List * @Description: 私有方法,获取泛型的TypeReference * @author Jecced * @param clazz * @return */ private static <T> JavaType List(Class<?> clazz) { return mapper.getTypeFactory().constructParametricType(ArrayList.class, clazz); } }
封装之后,调用更简单:
System.out.println("=====对象转换bytes====="); Person person = new Person("Jecced", 18, true); byte[] bytes = MsgPackUtil.toBytes(person); System.out.println(bytes.length); System.out.println(Arrays.toString(bytes)); System.out.println("=====bytes转对象====="); Person value = MsgPackUtil.toObject(bytes, Person.class); System.out.println(value); System.out.println("=====集合转换bytes====="); List<Person> list = new ArrayList<Person>(); list.add(new Person("Jecced", 18, true)); list.add(new Person("Ruby", 3, false)); bytes = MsgPackUtil.toBytes(list); System.out.println(bytes.length); System.out.println(Arrays.toString(bytes)); System.out.println("=====bytes转换集合====="); List<Person> list2 = MsgPackUtil.toList(bytes, Person.class); System.out.println(list2);
=====对象转换bytes===== 23 [-125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101, 18, -93, 115, 101, 120, -61] =====bytes转对象===== Person [name=Jecced, age=18, sex=true] =====集合转换bytes===== 45 [-110, -125, -92, 110, 97, 109, 101, -90, 74, 101, 99, 99, 101, 100, -93, 97, 103, 101, 18, -93, 115, 101, 120, -61, -125, -92, 110, 97, 109, 101, -92, 82, 117, 98, 121, -93, 97, 103, 101, 3, -93, 115, 101, 120, -62] =====bytes转换集合===== [Person [name=Jecced, age=18, sex=true], Person [name=Ruby, age=3, sex=false]]
写在最后,吧msgpack和json做一个简单的对比
public static void main(String[] args) throws IOException { List<Person> list = new ArrayList<Person>(); for(int i = 0 ; i < 10000; i ++){ list.add(new Person("name:" + i, i, 0 == i % 2)); } byte[] msgBytes = MsgPackUtil.toBytes(list); ByteArrayInputStream bis = new ByteArrayInputStream(msgBytes); File msgFile = File.createTempFile("msgpack_file", ".data"); msgFile.deleteOnExit(); FileOutputStream fos = new FileOutputStream(msgFile); saveTo(bis, fos); bis = null; fos = null; System.out.printf("msgpack序列化1w个对象后大小:%f kb\n", msgFile.length() / 1024.0d); byte[] jsonBytes = JSON.toJSONBytes(list); bis = new ByteArrayInputStream(jsonBytes); File jsonFile = File.createTempFile("json_file", ".data"); jsonFile.deleteOnExit(); fos = new FileOutputStream(jsonFile); saveTo(bis, fos); bis = null; fos = null; System.out.printf("json序列化1w个对象后大小:%f kb\n", jsonFile.length() / 1024.0d); } public static void saveTo(InputStream is, OutputStream out) throws IOException { try { byte[] buffer = new byte[1024 * 10]; int len = -1; while ((len = is.read(buffer)) != -1) { out.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { out.close(); is.close(); } }
msgpack序列化1w个对象后大小:271.981445 kb json序列化1w个对象后大小:422.637695 kb
由此可见,msgpack序列化后的大小确实比json小了很多很多
最新评论