Netty笔记13:序列化
- 电脑硬件
- 2025-09-11 21:54:01

Netty笔记1:线程模型
Netty笔记2:零拷贝
Netty笔记3:NIO编程
Netty笔记4:Epoll
Netty笔记5:Netty开发实例
Netty笔记6:Netty组件
Netty笔记7:ChannelPromise通知处理
Netty笔记8:ByteBuf使用介绍
Netty笔记9:粘包半包
Netty笔记10:LengthFieldBasedFrameDecoder
Netty笔记11:编解码器
Netty笔记12:模拟Web服务器
Netty笔记13:序列化
文章目录 MessagePack(多语言支持)jackson 这里我只是搞了 MessagePack和 Jackson这两种,他们使用和性能上算是不错的。在Java中实现序列化只需要implements Serializable ,但是这种方式限定了Java平台下,并且这种方式的性能也是很差的,不但内存占用高,消耗时间有长,具体的可以看这篇文章:几种Java常用序列化框架的选型与对比-阿里云开发者社区 (aliyun )
MessagePack(多语言支持) MessagePack is a binary serialization format. If you need a fast and compact alternative of JSON, MessagePack is your friend. For example, a small integer can be encoded in a single byte, and short strings only need a single byte prefix + the original byte array. MessagePack implementation is already available in various languages (See also the list in http://msgpack.org) and works as a universal data format. Message Pack specification: github /msgpack/msgpack/blob/master/spec.md MessagePack v7 (or later) is a faster implementation of the previous version v06, and supports all of the message pack types, including extension format. ---> MessagePack 是一种二进制序列化格式。如果你需要一个比 JSON 更快、更紧凑的替代方案,MessagePack 就是你的选择。例如,一个小整数可以仅用一个字节编码,短字符串只需要一个字节前缀加上原始字节数组。MessagePack 的实现已经存在于多种语言中(也可以参见列表),并且作为一个通用的数据格式工作。 MessagePack 规范: MessagePack v7(或更高版本)是之前版本 v06 的更快实现,并支持所有 MessagePack 类型,包括扩展格式。优点:
高效:节省空间;跨语言:MessagePack支持多种语言;易于使用:序列化和反序列化调用API就行,不像有些框架需要些配置,编译等复杂操作;缺点:
复杂数据类型支持不完善;引入依赖,限制最新版本是0.9.8
<dependency> <groupId>org.msgpack</groupId> <artifactId>msgpack-core</artifactId> <version>0.9.8</version> </dependency>发送端用MessagePack序列化
public class MsgEncoder extends MessageToByteEncoder<UserInfo> { @Override protected void encode(ChannelHandlerContext ctx, UserInfo msg, ByteBuf out) throws Exception { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try (MessagePacker mp = MessagePack.newDefaultPacker(bos);) { mp.packMapHeader(3); mp.packString("name").packString(msg.getName());; mp.packString("id").packInt(msg.getId()); mp.packString("data").packString(msg.getData()); // 设置完属性,记得调用这个方法将数据刷到bos mp.flush(); byte[] bytes = bos.toByteArray(); out.writeBytes(bytes); } } }接收端用户MessagePack反序列化
public class MsgDecoder extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { int length = in.readableBytes(); byte[] bytes = new byte[length]; in.readBytes(bytes);; try (MessageUnpacker mp = MessagePack.newDefaultUnpacker(bytes)) { ImmutableValue value = mp.unpackValue(); if (!value.isMapValue()) { throw new Exception("数据格式不对"); } Map<Value, Value> map = value.asMapValue().map(); String name = map.get(ValueFactory.newString("name")).asStringValue().asString(); int id = map.get(ValueFactory.newString("id")).asIntegerValue().asInt(); String data = map.get(ValueFactory.newString("data")).asStringValue().asString(); UserInfo info = new UserInfo(); info.setName(name); info.setId(id); info.setData(data); System.out.printf("读取到数据:name:%s, id:%d, data:%s%n", name, id, data); out.add(info); } } } jacksonjackson有官方提供的示例,建议去看看:msgpack-java/msgpack-jackson at main · msgpack/msgpack-java · GitHub
<dependency> <groupId>org.msgpack</groupId> <artifactId>jackson-dataformat-msgpack</artifactId> <version>0.9.8</version> </dependency>需要注意:ObjectMapper是线程安全的,这里示例为了读者清晰的思路写在一起了,实际开发中应该是全局配置或特殊配置的。
发送到编码器 public class MsgJacksonEncoder extends MessageToByteEncoder<UserInfo> { @Override protected void encode(ChannelHandlerContext ctx, UserInfo msg, ByteBuf out) throws Exception { // 方法一 ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); byte[] bytes = objectMapper.writeValueAsBytes(msg); out.writeBytes(bytes); // 方法二 // ObjectMapper objectMapper2 = new MessagePackMapper(); // byte[] bytes2 = objectMapper2.writeValueAsBytes(msg); // out.writeBytes(bytes2); } } 接收端解码器 public class MsgJacksonDecoder extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { int length = in.readableBytes(); byte[] bytes = new byte[length]; in.readBytes(bytes);; // 方法一 ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory()); // UserInfo info = objectMapper.readValue(bytes, UserInfo.class); // System.out.println("读取到数据:" + JSON.toJSONString(info)); // 方法二 // ObjectMapper objectMapper2 = new MessagePackMapper(); // UserInfo info2 = objectMapper2.readValue(bytes, UserInfo.class); // System.out.println("读取到数据:" + JSON.toJSONString(info2)); // 类型转换的另一种方式 TypeReference<UserInfo> typeReference = new TypeReference<UserInfo>(){}; UserInfo info3 = objectMapper.readValue(bytes, typeReference); System.out.println("读取到数据:" + JSON.toJSONString(info3)); } }需要注意:ObjectMapper是线程安全的,这里示例为了读者清晰的思路写在一起了,实际开发中应该是全局配置或特殊配置的。
Netty笔记13:序列化由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Netty笔记13:序列化”