JAVA序列化 结合 Netty
来源:互联网 发布:怎样才能加入淘宝商城 编辑:程序博客网 时间:2024/05/20 00:38
序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例
序列化的作用
- 把对象的字节序列永久地保存到硬盘上(通常存放在一个文件中);
- 在网络上传送对象的字节序列。
当你想把的内存中的对象保存到一个文件中或者数据库中时候;
当你想用套接字在网络上传送对象的时候;
当你想通过RMI传输对象的时候;
Serializable接口
public class Message implements Serializable{ private static final long serialVersionUID = 1L; private long id; //id private long receiveId; //接受者 private long sendId; //发送者 private String content; //内容 private int type; //类型 private int state; //状态 private Date createTime; //创建时间 /** * @return the id */ public long getId() { return id; } /** * @param id the id to set */ public void setId(long id) { this.id = id; } /** * @return the receive */ public long getReceiveId() { return receiveId; } /** * @param receive the receive to set */ public void setReceiveId(long receiveId) { this.receiveId = receiveId; } /** * @return the send */ public long getSendId() { return sendId; } /** * @param send the send to set */ public void setSendId(long sendId) { this.sendId = sendId; } /** * @return the content */ public String getContent() { return content; } /** * @param content the content to set */ public void setContent(String content) { this.content = content; } /** * @return the type */ public int getType() { return type; } /** * @param type the type to set */ public void setType(int type) { this.type = type; } /** * @return the state */ public int getState() { return state; } /** * @param state the state to set */ public void setState(int state) { this.state = state; } /** * @return the createTime */ public Date getCreateTime() { return createTime; } /** * @param createTime the createTime to set */ public void setCreateTime(Date createTime) { this.createTime = createTime; } public String toString() { return "message [id=" + id + ", receiveId=" + receiveId + ", sendId=" + sendId + ", content="+ content + ", type=" + type + ", state=" + state + ", createTime=" + createTime + "]"; }}
Protobuf
简述
Protocol Buffers (ProtocolBuffer/ protobuf )是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。现阶段支持C++、JAVA、Python等三种编程语言。
- 结构化数据存储方式(XML、 JSON)
- 高效的编解码性能
- 语言无关、平台无关、扩展性好
- 官方支持JAVA、C++、Python三种语言
使用过程:
完整示例 : http://download.csdn.net/detail/hq0556/9826665
1. 选择版本下载protobuf : https://github.com/google/protobuf/releases;
2. 项目加入protobuf-java.jar包;
3. 编写xxx.proto;
4. cmd进入protoc.exe文件夹下:protoc.exe –java_out=./ xxx.proto
示例
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>2.5.0</version></dependency>
编写message.proto,与上例Message类对应
package com.heqing.netty.bean.protobuf;option java_package = "com.heqing.netty.bean.protobuf"; option java_outer_classname = "ProtobufProto"; message testBuf { required int64 id = 1; required int64 receiveId = 2; required int64 sendId = 3; required string content= 4; required int32 type = 5; required int32 state = 6; required int64 createTime = 7;}
public class TestMessage { private static byte[] encode(ProtobufProto.testBuf msg) { return msg.toByteArray(); } private static ProtobufProto.testBuf decode(byte[] body) throws InvalidProtocolBufferException { return ProtobufProto.testBuf.parseFrom(body); } private static ProtobufProto.testBuf createMessage() { ProtobufProto.testBuf.Builder builder = ProtobufProto.testBuf.newBuilder(); builder.setId(1l); builder.setReceive(10001l); builder.setSend(10002l); builder.setContent("this is test"); builder.setType(0); builder.setState(0); builder.setCreateTime(System.currentTimeMillis()); return builder.build(); } public static void main(String[] args) { try { ProtobufProto.testBuf msg1 = createMessage(); System.out.println("11--->"+msg1.toString()); ProtobufProto.testBuf msg2 = decode(encode(msg1)); System.out.println("22--->"+msg1.toString()); System.out.println("33--->"+msg1.equals(msg2)); } catch(Exception e) { e.printStackTrace(); } }}
结合Netty示例
public class ProtobufServer { public void bind(int port) throws Exception { //EventLoopGroup是用来处理IO操作的多线程事件循环器 //bossGroup 用来接收进来的连接 EventLoopGroup bossGroup = new NioEventLoopGroup(); //workerGroup 用来处理已经被接收的连接 EventLoopGroup workerGroup = new NioEventLoopGroup(); try { //启动 NIO 服务的辅助启动类 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) //配置 Channel .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ProtobufVarint32FrameDecoder()); //处理半包 ch.pipeline().addLast(new ProtobufDecoder(ProtobufProto.testBuf.getDefaultInstance())); ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender()); ch.pipeline().addLast(new ProtobufEncoder()); // 注册handler ch.pipeline().addLast(new ProtobufServerHandler()); } }) .childOption(ChannelOption.SO_KEEPALIVE, true); // 绑定端口,开始接收进来的连接 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 。 f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new ProtobufServer().bind(port); } }
public class ProtobufServerHandler extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ProtobufProto.testBuf message = (ProtobufProto.testBuf)msg; System.out.println("send---->"+message.toString()); ProtobufProto.testBuf.Builder builder = ProtobufProto.testBuf.newBuilder(); builder.setId(2l); builder.setReceive(10002l); builder.setSend(10001l); builder.setContent("this is server"); builder.setType(0); builder.setState(0); builder.setCreateTime(System.currentTimeMillis()); ctx.writeAndFlush(builder.build()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 当出现异常就关闭连接 cause.printStackTrace(); ctx.close(); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } }
public class ProtobufClient { public void connect(String host, int port) throws Exception { EventLoopGroup workerGroup = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(workerGroup) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ProtobufVarint32FrameDecoder()); //处理半包 ch.pipeline().addLast(new ProtobufDecoder(ProtobufProto.testBuf.getDefaultInstance())); ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender()); ch.pipeline().addLast(new ProtobufEncoder()); // 注册handler ch.pipeline().addLast(new ProtobufClientHandler()); } }); // Start the client. ChannelFuture f = b.connect(host, port).sync(); // Wait until the connection is closed. f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { ProtobufClient client = new ProtobufClient(); client.connect("127.0.0.1", 8080); } }
public class ProtobufClientHandler extends ChannelHandlerAdapter{ // 连接成功后,向server发送消息 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ProtobufProto.testBuf.Builder builder = ProtobufProto.testBuf.newBuilder(); builder.setId(1l); builder.setReceive(10001l); builder.setSend(10002l); builder.setContent("this is send"); builder.setType(0); builder.setState(0); builder.setCreateTime(System.currentTimeMillis()); ctx.writeAndFlush(builder.build()); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ProtobufProto.testBuf message = (ProtobufProto.testBuf)msg; System.out.println("receive---->"+message.toString()); } public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 当出现异常就关闭连接 cause.printStackTrace(); ctx.close(); }}
JBoss Marshalling
JBoss Marshalling 是一个Java 对象序列化包,对 JDK 默认的序列化框架进行了优化,但又保持跟 Java.io.Serializable 接口的兼容,同时增加了一些可调的参数和附件的特性, 这些参数和附加的特性, 这些参数和特性可通过工厂类进行配置.
<dependency> <groupId>org.jboss.marshalling</groupId> <artifactId>jboss-marshalling</artifactId> <version>1.4.11.Final</version></dependency><dependency> <groupId>org.jboss.marshalling</groupId> <artifactId>jboss-marshalling-serial</artifactId> <version>1.4.11.Final</version></dependency>
public class MarshallingServer { public void bind(int port) throws Exception { // 配置服务端的NIO线程组 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) { ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder()); ch.pipeline().addLast(new MarshallingServerHandler()); } }); // 绑定端口,同步等待成功 ChannelFuture f = b.bind(port).sync(); // 等待服务端监听端口关闭 f.channel().closeFuture().sync(); } finally { // 优雅退出,释放线程池资源 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new MarshallingServer().bind(port); }}
@Sharablepublic class MarshallingServerHandler extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Message req = (Message) msg; System.out.println("this send msg --> ["+ req.toString() + "]"); if (2 == req.getId()) { ctx.writeAndFlush(resp(req.getId())); } } private Message resp(long subReqID) { Message resp = new Message(); resp.setId(subReqID); resp.setContent("客户端,我收到你的消息了!"); return resp; } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close();// 发生异常,关闭链路 }}
public final class MarshallingCodeCFactory { /** * 创建Jboss Marshalling解码器MarshallingDecoder * * @return */ 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, 1024); return decoder; } /** * 创建Jboss Marshalling编码器MarshallingEncoder * * @return */ public static MarshallingEncoder buildMarshallingEncoder() { final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial"); final MarshallingConfiguration configuration = new MarshallingConfiguration(); configuration.setVersion(5); MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration); MarshallingEncoder encoder = new MarshallingEncoder(provider); return encoder; }}
public class MarshallingClient { public void connect(int port, String host) throws Exception { // 配置客户端NIO线程组 EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group).channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder()); ch.pipeline().addLast(new MarshallingClientHandler()); } }); // 发起异步连接操作 ChannelFuture f = b.connect(host, port).sync(); // 当代客户端链路关闭 f.channel().closeFuture().sync(); } finally { // 优雅退出,释放NIO线程组 group.shutdownGracefully(); } } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { int port = 8080; new MarshallingClient().connect(port, "127.0.0.1"); }}
public class MarshallingClientHandler extends ChannelHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) { for (int i = 0; i < 10; i++) { ctx.write(subReq(i)); } ctx.flush(); } private Message subReq(int i) { Message req = new Message(); req.setId(i); req.setContent("服务端,你收到我的消息了吗?"); return req; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("this server msg --> [" + msg + "]"); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); }}
- JAVA序列化 结合 Netty
- netty java序列化
- Netty之java序列化
- 5、netty-java序列化(netty学习笔记)
- Netty 权威指南之java 序列化
- Netty的java序列化实现
- 《netty权威指南》6.1JAVA序列化的缺点
- [netty]-消息编解码之Java原生序列化
- Netty编解码框架:Java序列化、Protobuf、 Marshalling
- netty编解码之java原生序列化
- java nio socket结合netty传输文件
- Netty发送序列化对象
- Netty中处理写序列化异常
- netty 对象序列化传输示例
- Netty学习7-序列化原理
- Netty学习9-序列化框架protocbuf
- 利用Netty的ChannelBuffer自定义序列化
- jboss marshell序列化整合netty
- 数学意识:数学模型:数学性质
- JAVA-练习MyShopping循环录入会员信息
- Android 10个快速开发框架:Afinal、ThinkAndroid、AndBase、KJFrameForAndroid、SmartAndroid、xUtils
- jhipster生成的工程war包部署到tomcat中,tomcat正常启动,但一直不加载项目的问题原因。
- 粉红噪声发生器
- JAVA序列化 结合 Netty
- 从CString转成DWORD
- 基于 Django1.10 文档的深入学习(7)—— Configuring applications
- android 自定义View--圆环颜色选择器
- cxf调用webService
- Spring中IOC与AOP的理解
- Linux运维-Linux系统日常管理
- Redis缓存工具类(夏顺辉)
- std::mutex std::unique_lock std::lock_guard std::recursive_mutex的理解