一、简介

JBoss Marshalling是一个Java对象序列化包,对JDK默认的序列化框架进行了优化,但又保持和java.io.Serializable接口的兼容。

二、Marshalling开发环境准备

1、下载类库

由于只涉及到Marshalling的序列化类库,因此只需要下载jboss-marshalling-1.3.0.CR9.jar和jboss-marshalling-serial-1.3.0.CR9.jar包即可,下载地址如下:https://www.jboss.org/jbossmarshalling/downloads

2、将下载的类库build到classpath下:

二、Netty的Marshalling开发

1、Marshalling编解码器工厂类:

import org.jboss.marshalling.MarshallerFactory;
import org.jboss.marshalling.Marshalling;
import org.jboss.marshalling.MarshallingConfiguration;import io.netty.handler.codec.marshalling.DefaultMarshallerProvider;
import io.netty.handler.codec.marshalling.DefaultUnmarshallerProvider;
import io.netty.handler.codec.marshalling.MarshallerProvider;
import io.netty.handler.codec.marshalling.MarshallingDecoder;
import io.netty.handler.codec.marshalling.MarshallingEncoder;
import io.netty.handler.codec.marshalling.UnmarshallerProvider;//Marshalling编解码器的工厂类
public final class MarshallingCodeCFactory
{//创建JBoss Marshalling解码器public static MarshallingDecoder buildMarshallingDecoder(){final MarshallerFactory marshallerFactory=Marshalling.getProvidedMarshallerFactory("serial");final MarshallingConfiguration configuration=new MarshallingConfiguration();configuration.setVersion(5);UnmarshallerProvider provider=new DefaultUnmarshallerProvider(marshallerFactory, configuration);MarshallingDecoder decoder=new MarshallingDecoder(provider);return decoder;}//创建JBoss Marshalling编码器public static MarshallingEncoder buildMarshallingeEncoder(){//"serial"表示创建的是Java序列化工厂对象final MarshallerFactory marshallerFactory=Marshalling.getProvidedMarshallerFactory("serial");final MarshallingConfiguration configuration=new MarshallingConfiguration();configuration.setVersion(5);MarshallerProvider provider=new DefaultMarshallerProvider(marshallerFactory, configuration);//MarshallingEncoder用于将实现序列化接口的POJO对象序列化为二进制字节数组MarshallingEncoder encoder=new MarshallingEncoder(provider);return encoder;}
}

2、服务端代码:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;public class SubReqServer
{public void bind(int port)throws Exception{EventLoopGroup bossGroup=new NioEventLoopGroup();EventLoopGroup workerGroup=new NioEventLoopGroup();try{ServerBootstrap b=new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch)throws Exception{ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingeEncoder());ch.pipeline().addLast(new SubReqServerHandler());}});ChannelFuture f=b.bind(port).sync();f.channel().closeFuture().sync();}catch (Exception e){e.printStackTrace();}finally{bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public static void main(String[] args)throws Exception{int port =8888;if (args!=null&&args.length>0){port=Integer.valueOf(args[0]);}new SubReqServer().bind(port);}
}

3、服务端网络I/O事件类:

import com.exp.netty.chapter07.SubscribeReq;
import com.exp.netty.chapter07.SubscribeResp;import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;public class SubReqServerHandler extends ChannelHandlerAdapter
{@Overridepublic void channelRead(ChannelHandlerContext ctx,Object msg)throws Exception{SubscribeReq req=(SubscribeReq)msg;if ("test".equalsIgnoreCase(req.getUserName())){System.out.println("Service accept client subscribe req : ["+req.toString()+"]");}ctx.writeAndFlush(resp(req.getSubReqID()));}private SubscribeResp resp(int subReqID){SubscribeResp resp=new SubscribeResp();resp.setSubReqID(subReqID);resp.setRespCode(0);resp.setDesc("Netty book order succeed, 3 days later, sent to the designated address");return resp;}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx,Throwable cause){cause.printStackTrace();ctx.close();}
}

4、客户端代码:

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;public class SubReqClient
{public void connect(int port,String host)throws Exception{EventLoopGroup g=new NioEventLoopGroup();try{Bootstrap b=new Bootstrap();b.group(g).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch)throws Exception{ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingeEncoder());ch.pipeline().addLast(new SubReqClientHandler());}});ChannelFuture f=b.connect(host, port).sync();f.channel().closeFuture().sync();}catch (Exception e){e.printStackTrace();}finally{g.shutdownGracefully();}}public static void main(String[] args)throws Exception{int port =8888;if (args!=null&&args.length>0){port=Integer.valueOf(args[0]);}new SubReqClient().connect(port, "127.0.0.1");}
}

5、客户端网络I/O事件类:

import com.exp.netty.chapter07.SubscribeReq;import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;public class SubReqClientHandler extends ChannelHandlerAdapter
{public SubReqClientHandler(){}@Overridepublic void channelActive(ChannelHandlerContext ctx){for (int i = 0; i < 10; i++ ){ctx.write(subReq(i));}ctx.flush();}private SubscribeReq subReq(int i){SubscribeReq req=new SubscribeReq();req.setAddress("杭州市西湖风景区");req.setPhoneNumber("13888888888");req.setProductName("Netty 权威指南");req.setSubReqID(i);req.setUserName("test");return req;}@Overridepublic void channelRead(ChannelHandlerContext ctx,Object msg){System.out.println("Receive server response : ["+msg+"]");}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx)throws Exception{ctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx,Throwable cause){cause.printStackTrace();ctx.close();}
}

这里客户端连续发送了10条消息都成功得到响应,说明模拟的TCP的粘包/拆包场景结果正确,因此Netty的Marshalling编解码器支持半包和粘包的处理,因此我们只需要将Marshalling的编码器和解码器加入ChannelPipeline中就可以实现对Marshalling序列化的支持,而且也方便了与JBoss内部模块的远程通信。

参考书籍《Netty权威指南》

JBoss Marshalling编解码相关推荐

  1. Netty详解(六):Netty 编解码技术

    1. 概述 基于Java提供的对象输入/输出流ObjectInputStream和ObjectOutputStream,可以直接把Java对象作为可村粗的字节数组写入文件,也可以传输到网络上去.Jav ...

  2. Netty之编解码技术(四)

    通常我们习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decode)称为反序列化(deseriali ...

  3. Netty系列之Netty编解码框架分析

    1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decod ...

  4. Netty(十四)(中级篇)MessagePack编解码

    一,客户端 假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术 ...

  5. 贪心算法简单实践 -- 分糖果、钱币找零、最多区间覆盖、哈夫曼编解码

    1. 贪心算法概览 贪心算法是一种算法思想.希望能够满足限制的情况下将期望值最大化.比如:Huffman编码,Dijkstra单源最短路径问题,Kruskal最小生成树 等问题都希望满足限制的情况下用 ...

  6. 通过OpenSSL的接口实现Base64编解码

    对openssl genrsa产生的rsa私钥pem文件,使用普通的base64解码会有问题,如使用https://blog.csdn.net/fengbingchun/article/details ...

  7. FFmpeg在Windows上通过dshow编解码方式设置为mjpeg并实时显示测试代码

    Windows上默认的内置摄像头一般支持两种编解码格式:rawvideo和mjpeg.在调用FFmpeg接口时默认的采用rawvideo.这里通过DirectShow实现为mjpeg进行编解码. 通过 ...

  8. Linux下通过v4l2获取视频设备名、支持的编解码及视频size列表实现

    早些时候给出了在Windows下通过dshow获取视频设备信息的实现,包括获取视频设备名.获取每种视频设备支持的编解码格式列表.每种编解码格式支持的video size列表,见:https://blo ...

  9. 通过Windows DShow获取设备名、支持的编解码及视频size列表实现

    之前在https://blog.csdn.net/fengbingchun/article/details/102641967中介绍过通过DShow获取Camera视频的实现,即调用VideoCapt ...

最新文章

  1. 容器安全最佳实践入门
  2. 【软件工程实践】结对项目-四则运算 “软件”之升级版
  3. dedecms右侧悬浮_织梦dedecms网站上添加漂浮广告
  4. c语言程序设计网络作业,北语网院17春《C语言程序设计》作业_2满分答案
  5. LINUX安装中文字体SimHei
  6. 安装基于Ubuntu的微信小程序开发工具
  7. Opencv之threshold
  8. 计算机窗口显示不出来的,任务栏不显示打开的窗口,详细教您打开的窗口在任务栏上显示不出来...
  9. html代码清明节,清明节网上祭祀网站登陆地址:http://www.tsingming.com/index.html
  10. 如何卸载冰点还原精灵
  11. python无法打开h5权限_求助:python post请求访问不到数据
  12. 看看十二星座哪个更适合当程序员
  13. website for all kinds of courses
  14. swift 设置 pickerView 为黑底白字
  15. PostgreSQL 基础模块---表和元组组织方式
  16. 【假期层次晋升计划】四点共圆、托勒密定理——2014年6月25日
  17. 象QQ早上那样的新闻切换
  18. Xshell找不到MSVCP110.dll与MSVCR110.dll
  19. C语言之消息队列MQ
  20. 字典树(查找树)入门

热门文章

  1. 安卓源码(一)下载与同步
  2. Ubuntu 20 LTS 安装kubenetes 1.25
  3. 特写 | 被银行降薪的“金融民工”
  4. 大学生英语四级备战之③听力
  5. 蹒跚学步——工作日记20070306
  6. 【科研入门】Latex论文写作辅助工具及期刊查询网站
  7. 知乎、清华大学联合承办CCIR2018评测 寻找中国AI潜力股
  8. dfs--选择困难症牛客
  9. 关于Serializable的一个形象的例子
  10. 如何解决choregraphe由于VCOMP120.DLL丢失而导致的闪退问题