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. mysql 备份和恢复的两条命令

    压缩备份: 1.mysqldump -h localhost -u root -p dbname | gzip > dbname.sql.gz 压缩恢复: 1.gunzip < dbnam ...

  2. Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

    Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...

  3. Eclipse 项目以非gradle方式导入Android Studio

    对于以前习惯了Eclipse ide的开发这来说,要把项目导入到studio是一件很不愿接受的事情,但是...毕竟人家官方都给出建议了,并且年后会逐渐被淘汰 如下图所示是一个典型的eclipse项目. ...

  4. 嵌入式C语言查表法的项目应用

    嵌入式C实战项目开发技巧:如果对一个有规律的数组表进行位移操作 就像下面的这个表 之前写过上面这个标题的一篇文章,讲的是以位移的方式去遍历表中的数据,效率非常高,但是,如果要实现一个乱序的流水灯或者跑 ...

  5. 02_Nginx基本配置与参数说明 + 辅助命令

     Nginx基本配置与参数说明,下面是nginx.conf配置文件 #运行用户 #user  nobody; worker_processes  2; #全局错误日志及PID文件 #error_l ...

  6. g++和gcc的相同点和区别

    gcc和g++的区别和联系 gcc和g++都是GNU(一个组织)的编译器. 1.对于.c后缀的文件,gcc把它当做是C程序:g++当做是C++程序: 2.对于.cpp后缀的文件,gcc和g++都会当做 ...

  7. umask函数的用法 - 如何进行权限位的设置

    下面程序创建了两个文件,创建foo文件时,umask值为0,创建第二个时,umask值禁止所有组和其他用户的访问权限. 测试结果: 测试结果可以看出更改进程的文件模式掩码并不影响其父进程(常常是she ...

  8. 做自己的软件的Gallery(一)

    先上效果图: 如图,android默认也有Gallery,很多软件在调用时,都是使用自己的Gallery,一方面好维护,另外一方面可以做优化.要做成以上样式,图片加载类起至关重要,一不小心,就好OOM ...

  9. 让opencv程序在没有安装opencv的电脑上运行

    经常需要把用opencv写的程序拿到没有装opencv的电脑上去运行和演示,要让opencv程序脱离opencv环境,一般有两种方法: 一种是动态链接opencv,即把相应的dll拷贝到exe所在目录 ...

  10. bash配置文件说明

    login shell: /etc/profile 所有用户全局设定,它首先会调用以下文件:     /etc/inputrc     /etc/profile.d/*.sh     /etc/sys ...