JDK提供了ObjectOutputStream和ObjectInputStream,用于通过网络对POJO的基本数据类型和图进行序列化和反序列化。该API并不复杂,而且可以被应用于任何实现了java.io.Serializable接口的对象。但是它的性能也不是非常高效的。在这一节中,我们将看到Netty必须为此提供什么。

一、JDK序列化

如果你的应用程序必须要和使用了ObjectOutputStream和ObjectInputStream的远程节点交互,并且兼容性也是你最关心的,那么JDK序列化将是正确的选择。下表列出了Netty提供的用于和JDK进行互操作的序列化类。

JDK序列化编解码器

CompatibleObjectDecoder和使用JDK序列化的非基于Netty的远程节点进行互操作的解码器
CompatibleObjectEncoder 和使用JDK序列化的非基于Netty的远程节点进行互操作的编码器
ObjectDecoder 构建于JDK 序列化之上的使用自定义的序列化来解码的解码器;当没有其他的外部依赖时,它提供了速度上的改进。否则其他的序列化实现更加可取
ObjectEncoder 构建于JDK 序列化之上的使用自定义的序列化来编码的编码器;当没有其他的外部依赖时,它提供了速度上的改进。否则其他的序列化实现更加可取

二、使用JBoss Marshalling 进行序列化

如果你可以自由地使用外部依赖,那么JBossMarshalling将是个理想的选择:它比JDK序列化最多快3倍,而且也更加紧凑。在JBossMarshalling官方网站主页上的概述中对它是这么定义的:

JBoss Marshalling是一种可选的序列化API,它修复了在JDK序列化API中所发现的许多问题,同时保留了与java.io.Serializable及其相关类的兼容性,并添加了几个新的可调优参数以及额外的特性,所有的这些都是可以通过工厂配置(如外部序列化器、类/实例查找表、类解析以及对象替换等)实现可插拔的。

Netty通过下表所示的两组解码器/编码器对为Boss Marshalling 提供了支持。第一组兼容只使用JDK序列化的远程节点。第二组提供了最大的性能,适用于和使用JBoss Marshalling的远程节点一起使用。

JBoss Marshalling 编解码器

CompatibleMarshallingDecoder 与只使用JDK 序列化的远程节点兼容
MarshallingDecoder 适用于使用JBoss Marshalling 的节点。这些类必须一起使用。

以下代码清单展示了如何使用MarshallingDecoder 和MarshallingEncoder。同样,几乎只是适当地配置ChannelPipeline罢了。

使用JBoss Marshalling

public class MarshallingInitializer extends ChannelInitializer<Channel> {
private final MarshallerProvider marshallerProvider;
private final UnmarshallerProvider unmarshallerProvider; public MarshallingInitializer(UnmarshallerProvider unmarshallerProvider,
MarshallerProvider marshallerProvider) {
this.marshallerProvider = marshallerProvider;
this.unmarshallerProvider = unmarshallerProvider;
} @Override
protected void initChannel(Channel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new MarshallingDecoder(unmarshallerProvider));// 添加MarshallingDecoder以将ByteBuf 转换为POJO
pipeline.addLast(new MarshallingEncoder(marshallerProvider));// 添加MarshallingEncoder 以将POJO转换为ByteBuf
pipeline.addLast(new ObjectHandler());// 添加ObjectHandler,以处理普通的实现了Serializable 接口的POJO
} public static final class ObjectHandler extends SimpleChannelInboundHandler<Serializable> {
@Override
public void channelRead0(ChannelHandlerContext channelHandlerContext, Serializable serializable)
throws Exception {
// Do something
}
}
}

三、通过Protocol Buffers 序列化

Netty序列化的最后一个解决方案是利用Protocol Buffers的编解码器,它是一种由Google公司开发的、现在已经开源的数据交换格式。可以在https://github.com/google/protobuf找到源代码。
Protocol Buffers 以一种紧凑而高效的方式对结构化的数据进行编码以及解码。它具有许多的编程语言绑定,使得它很适合跨语言的项目。表11-10 展示了Netty为支持protobuf 所提供的ChannelHandler实现。

Protobuf 编解码器

ProtobufDecoder 使用protobuf对消息进行解码
ProtobufEncoder 使用protobuf对消息进行编码
ProtobufVarint32FrameDecoder 根据消息中的Google Protocol Buffers 的“Base 128 Varints整型长度字段值动态地分割所接收到的ByteBuf
ProtobufVarint32LengthFieldPrepender 向ByteBuf 前追加一个Google Protocal Buffers 的“Base128 Varints”整型的长度字段值

在这里我们又看到了,使用protobuf只不过是将正确的ChannelHandler添加到ChannelPipeline 中,如下代码所示。

使用protobuf

public class ProtoBufInitializer extends ChannelInitializer<Channel> {
private final MessageLite lite; public ProtoBufInitializer(MessageLite lite) {
this.lite = lite;
} @Override
protected void initChannel(Channel ch) throws Exception {
  ChannelPipeline pipeline = ch.pipeline();
  pipeline.addLast(new ProtobufVarint32FrameDecoder());// 添加ProtobufVarint32FrameDecoder以分隔帧
  pipeline.addLast(new ProtobufEncoder()); // 添加ProtobufEncoder以处理消息的编码
  pipeline.addLast(new ProtobufDecoder(lite));// 添加ProtobufDecoder以解码消息
  pipeline.addLast(new ObjectHandler());// 添加ObjectHandler以处理解码消息
} public static final class ObjectHandler extends SimpleChannelInboundHandler<Object> {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
// Do something with the object
}
}
}

由Netty专门的解码器和编码器所支持的不同的序列化选项:标准JDK序列化、JBoss Marshalling以及Google的Protocol Buffers。

Netty中如何序列化数据的更多相关文章

  1. Netty(五):Netty中如何序列化数据

    JDK提供了ObjectOutputStream和ObjectInputStream,用于通过网络对POJO的基本数据类型和图进行序列化和反序列化.该API并不复杂,而且可以被应用于任何实现了java ...

  2. Netty中的装饰者模式

    装饰者的应用 所谓装饰者,说白了,目的就是对现有的对象进行增强,装饰者设计模式最大的优点就是,它在扩展类原有功能的基础上还避免的类爆炸的情况 Netty中的装饰者模式的应用 ByteBuf是netty ...

  3. Java中如何序列化一个对象(转)

    转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/380 ...

  4. netty系列之:netty中的核心编码器bytes数组

    目录 简介 byte是什么 netty中的byte数组的工具类 netty中byte的编码器 总结 简介 我们知道netty中数据传输的核心是ByteBuf,ByteBuf提供了多种数据读写的方法,包 ...

  5. Netty(五)序列化protobuf在netty中的使用

    protobuf是google序列化的工具,主要是把数据序列化成二进制的数据来传输用的.它主要优点如下: 1.性能好,效率高: 2.跨语言(java自带的序列化,不能跨语言) protobuf参考文档 ...

  6. Netty中如何写大型数据

    因为网络饱和的可能性,如何在异步框架中高效地写大块的数据是一个特殊的问题.由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知ChannelFuture.当这种情况发生时,如 ...

  7. 在Asp.Net Core 3.0中如何使用 Newtonsoft.Json 库序列化数据

    在.Net Core 3.0中 内置了一套Json序列化/反序列化方案,默认可以不再依赖,不再支持   Newtonsoft.Json. 但是.NET Core 3.0 System.Text.Jso ...

  8. Netty 中的内存分配浅析-数据容器

    本篇接续前一篇继续讲 Netty 中的内存分配.上一篇 先简单做一下回顾: Netty 为了更高效的管理内存,自己实现了一套内存管理的逻辑,借鉴 jemalloc 的思想实现了一套池化内存管理的思路: ...

  9. Netty中的那些坑

    Netty中的那些坑(上篇) 最近开发了一个纯异步的redis客户端,算是比较深入的使用了一把netty.在使用过程中一边优化,一边解决各种坑.儿这些坑大部分基本上是Netty4对Netty3的改进部 ...

随机推荐

  1. (视频) 《快速创建网站》 3.2 WordPress多站点及Azure在线编辑器 - 扔掉你的ftp工具吧,修改代码全部云端搞定

    本文是<快速创建网站>系列的第6篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 1. 网站管理平台WordPress和云计算平台Azure简介 (6分 ...

  2. cocos2d-x 读写 xml 文件

    cocos2d-x 读写 xml 文件 A product of cheungmine使用cocos2d-x开发2d游戏确实方便,但是对于一般的小游戏,经常需要的工作是UI布局设计和调整,代码改来改去 ...

  3. Testbench(转)

    本来还打算自己写下对Testbench的理解,后来发现百度百科名片解释得很好,所以就直接转了. 原文百度百科链接:http://baike.baidu.com/link?url=dxzsOAs32IE ...

  4. Linux - vim按键说明

    第一部份:一般模式可用的按钮说明,光标移动.复制贴上.搜寻取代等 移动光标的方法 h 或 向左箭头键(←) 光标向左移动一个字符 j 或 向下箭头键(↓) 光标向下移动一个字符 k 或 向上箭头键(↑ ...

  5. Android TV listView焦点平滑移动

    先上TV上效果图 Mark下思路: package com.test.ui; import java.lang.reflect.Method; import android.annotation.Su ...

  6. nasm中的表达式

    nasm表达式支持2个特殊的记号 $和$$;前者标识其所在源码行的开始处地址,所以你可以这样写死循环: jmp $ 而后者标识当前段开始处的地址,你可以通过: $-$$ 找出当前代码在段内的偏移. n ...

  7. 用JAVA代码获取Weblogic配置的JNDI 数据源连接

    第一步:生成与JDK版本对应的weblogicjar,利用cmd 进入到weblogic_home 路径下进入到server/lib目录,然后运行  JDK  1.6 命令 "java -j ...

  8. mongodb3.6 (五)net 客户端访问mongodb设置超时时间踩过的“坑”

    前言 在上一篇文章中,我们有提到net访问mongodb连接超时默认为30秒,这个时间在实际项目中肯定是太长的.而MongoClientSettings 也确是提供了超时属性,如下图: 可实际使用中, ...

  9. IT轮子系列(四)——使用Jquery+formdata对象 上传 文件

    前言 在MVC 中文件的上传,一般都采用控件: <h2>IT轮子四——文件上传</h2> <div> <input type="file" ...

  10. combination sum、permutation、subset(组合和、全排列、子集)

    combination sum I.permutation I.subsets  I 是组合和.全排列.子集的第一种情况,给定数组中没有重复的元素. combination sum II.permut ...