netty: marshalling传递对象,传输附件GzipUtils
netty: marshalling传递对象,传输附件GzipUtils
前端与服务端传输文件时,需要双方需要进行解压缩,也就是Java序列化。可以使用java进行对象序列化,netty去传输,但java序列化硬伤太多(无法跨语言,码流太大,性能太低),所以最好使用主流的编辑码框架来配合netty使用。此处使用的是JBossMarshalling框架。
用到的包:
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha2</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.jboss.marshalling/jboss-marshalling -->
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling</artifactId>
<version>2.0.0.CR1</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.jboss.marshalling/jboss-marshalling-serial -->
<dependency>
<groupId>org.jboss.marshalling</groupId>
<artifactId>jboss-marshalling-serial</artifactId>
<version>2.0.0.CR1</version>
</dependency>
用到的压缩包工具类:
gziputils.java
public class GzipUtils { public static byte[] gzip(byte[] data) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(bos);
gzip.write(data);
gzip.finish();
gzip.close();
byte[] ret = bos.toByteArray();
bos.close();
return ret;
} public static byte[] ungzip(byte[] data) throws Exception{
ByteArrayInputStream bis = new ByteArrayInputStream(data);
GZIPInputStream gzip = new GZIPInputStream(bis);
byte[] buf = new byte[1024];
int num = -1;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((num = gzip.read(buf, 0 , buf.length)) != -1 ){
bos.write(buf, 0, num);
}
gzip.close();
bis.close();
byte[] ret = bos.toByteArray();
bos.flush();
bos.close();
return ret;
} public static void main(String[] args) throws Exception{ //读取文件
String readPath = System.getProperty("user.dir") + File.separatorChar + "sources" + File.separatorChar + "Netty+3.1中文用户手册.doc.jpg";
File file = new File(readPath);
FileInputStream in = new FileInputStream(file);
byte[] data = new byte[in.available()];
in.read(data);
in.close(); System.out.println("文件原始大小:" + data.length);
//测试压缩 byte[] ret1 = GzipUtils.gzip(data);
System.out.println("压缩之后大小:" + ret1.length); byte[] ret2 = GzipUtils.ungzip(ret1);
System.out.println("还原之后大小:" + ret2.length); //写出文件
String writePath = System.getProperty("user.dir") + File.separatorChar + "receive" + File.separatorChar + "Netty+3.1中文用户手册.doc.jpg";
FileOutputStream fos = new FileOutputStream(writePath);
fos.write(ret2);
fos.close(); }
}
Request.java类
public class Request implements Serializable { /**
*
*/
private static final long serialVersionUID = 1L; private String id;
private String name;
private String requestMessage;
private byte[] attachment; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getRequestMessage() {
return requestMessage;
} public void setRequestMessage(String requestMessage) {
this.requestMessage = requestMessage;
} public byte[] getAttachment() {
return attachment;
} public void setAttachment(byte[] attachment) {
this.attachment = attachment;
} }
Response.java类
public class Response implements Serializable { /**
*
*/
private static final long serialVersionUID = 1L; private String id; private String name; private String responseMessage; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getResponseMessage() {
return responseMessage;
} public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
} }
MarshallingCodeCFactory.java
序列号编码解码类
public final class MarshallingCodeCFactory { /**
* 解码器
* @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对象,两个参数分别为provider和消息序列化后的最大长度
MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024*1024*1);
return decoder; } /**
* 编码器
* @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对象,参数为provider;
MarshallingEncoder encoder = new MarshallingEncoder(provider);
return encoder; }
}
开始开发client,server功能
server.java
public class Server { public static void main(String[] args) throws InterruptedException {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(boss, worker)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel ch) throws Exception {
// TODO Auto-generated method stub
//设置编码解码
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(new ServerHandler());
}
});
ChannelFuture cf = b.bind(8765).sync(); cf.channel().closeFuture().sync();
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
serverHandler.java
需要继承ChannelHandlerAdapter类
public class ServerHandler extends ChannelHandlerAdapter { @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// TODO Auto-generated method stub
//super.exceptionCaught(ctx, cause);
cause.printStackTrace();
ctx.close();
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// TODO Auto-generated method stub
//super.channelRead(ctx, msg);
Request request = (Request) msg;
System.out.println("Server: " + request.getId() + ","+request.getName()+","+request.getRequestMessage()); //接收附件 写入文件
byte[] attachment = GzipUtils.ungzip(request.getAttachment());
String path = System.getProperty("user.dir") + File.separatorChar + "receive" + File.separatorChar + request.getId() +".png";
FileOutputStream outputStream = new FileOutputStream(path);
outputStream.write(attachment);
outputStream.close(); //返回数据
Response response = new Response();
response.setId(request.getId());
response.setName("response: " + request.getName());
response.setResponseMessage("相应的内容: " + request.getRequestMessage());
ctx.writeAndFlush(response); } }
client.java类
public class Client { public static void main(String[] args) throws Exception { EventLoopGroup worker = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(worker)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel ch) throws Exception {
// TODO Auto-generated method stub
//设置编码解码
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture cf = b.connect("127.0.0.1", 8765).sync(); for(int i=0; i< 5; i++) {
Request request = new Request();
request.setId(i + "");
request.setName( "pro"+ i);
request.setRequestMessage("数据信息Client~Server:" + i); //发送附件
String path = System.getProperty("user.dir") + File.separatorChar + "resources" + File.separatorChar + "1.png";
File file = new File(path);
FileInputStream inputStream = new FileInputStream(file);
byte[] data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
request.setAttachment(GzipUtils.gzip(data));
cf.channel().writeAndFlush(request);
} System.out.println("user.dir: " + System.getProperty("user.dir") + File.separatorChar + "resources" + File.separatorChar + "1.png" ); cf.channel().closeFuture().sync();
worker.shutdownGracefully();
} }
ClientHandler.java类
需要继承ChannelHandlerAdapter类
public class ClientHandler extends ChannelHandlerAdapter { @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// TODO Auto-generated method stub
//super.exceptionCaught(ctx, cause);
cause.printStackTrace();
ctx.close();
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// TODO Auto-generated method stub
//super.channelRead(ctx, msg);
try {
Response response = (Response) msg;
System.out.println("Client : " + response.getId() + ","+response.getName()+","+response.getResponseMessage());
} finally {
// TODO: handle finally clause
ReferenceCountUtil.release(msg);
} } }
目录如下:
netty: marshalling传递对象,传输附件GzipUtils的更多相关文章
- netty: 编解码之jboss marshalling, 用marshalling进行对象传输
jboss marshalling是jboss内部的一个序列化框架,速度也十分快,这里netty也提供了支持,使用十分方便. TCP在网络通讯的时候,通常在解决TCP粘包.拆包问题的时候,一般会用以下 ...
- netty的对象传输
pom <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency> <grou ...
- Netty4.x中文教程系列(四) 对象传输
Netty4.x中文教程系列(四) 对象传输 我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持. 首先我们定义一个U ...
- Android 全局获取 Context 与使用 Intent 传递对象
=====================全局获取 Context======================== Android 开发中很多地方需要用到 Context,比如弹出 Toast.启动活 ...
- Android--Intent传递对象
Intent 传递对象通常有两种实现方式,Serializable 和 Parcelable: 一.Serializable:序列化,表示将一个对象转换成可存储或可传输的状态,序列化后的对象可以在网络 ...
- Intent传递对象——Serializable和Parcelable区别
为什么要将对象序列化? 1.永久性保存对象,保存对象的字节序列到本地文件中: 2.用过序列化对象在网络中传递对象: 3.通过序列化对象在进程间传递对象. 1.实现Serializable接口 Seri ...
- 使用HttpURLConnection实现在android客户端和服务器之间传递对象
一般情况下,客户端和服务端的数据交互都是使用json和XML,相比于XML,json更加轻量级,并且省流量,但是,无论我们用json还是用xml,都需要我们先将数据封装成json字符串或者是一个xml ...
- Android中的Parcel机制 实现Bundle传递对象
Android中的Parcel机制 实现了Bundle传递对象 使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这种传递对象的方式需要用到Android Parc ...
- 为什么Intent传递对象的时候必须要将对象序列化呢?
Intent可以算是四大组件之间的胶水,比如在Activity1与Activity2之间传递对象的时候,必须要将对象序列化, 可是为什么要将对象序列化呢? Intent在启动其他组件时,会离开当前应用 ...
随机推荐
- Word 中直引号和弯引号的相互替换
直引号替换成弯引号 弯引号替换成直引号 未完 ...... 点击访问原文(进入后根据右侧标签,快速定位到本文)
- 【C#】上机实验八
1. 设计一个窗体应用程序,模拟写字板应用程序的基本功能.具体功能要求如下: (1)“文件”菜单中有“新建”.“打开”.“保存”.“退出”子菜单. (2)“编辑”菜单中有“剪切”.“复制”.“粘贴”. ...
- kafka和zookeeper安装部署(版本弄不好就是坑)
yum install -y unzip zip 配置host vi /etc/host172.19.68.10 zk1 1. zookeeper zookeeper下载地址 http://mirro ...
- Python之TensorFlow的数据的读取与存储-2
一.我们都知道Python由于GIL的原因导致多线程并不是真正意义上的多线程.但是TensorFlow在做多线程使用的时候是吧GIL锁放开了的.所以TensorFlow是真正意义上的多线程.这里我们主 ...
- .Net Jpush极光推送
1.首先登陆极光官网注册账号 https://www.jiguang.cn/push 2.注册成功后,在应用管理中创建应用
- Abp session和Cookie
问道 面向Abp 在面向服务的时候,Session 干嘛用? 先把Session 的作用说了,但是在微服务环境下给忽略了,相当于忽略了核心. Session 只是个功能.就是根据Cookie 的Ses ...
- docker第一章--介绍和安装
- python day 9: xlm模块,configparser模块,shutil模块,subprocess模块,logging模块,迭代器与生成器,反射
目录 python day 9 1. xml模块 1.1 初识xml 1.2 遍历xml文档的指定节点 1.3 通过python手工创建xml文档 1.4 创建节点的两种方式 1.5 总结 2. co ...
- foundation-cli创建项目出错的解决方案
使用foundation-cli创建项目时,如果当前的node版本是12的话就会出现如下错误: fs.js:27 const { Math, Object } = primordials; ^ Ref ...
- day30-python之socket
1.iter补充 # l=['a','b','c','d'] # # def test(): # return l.pop() # # x=iter(test,'b') # print(x.__nex ...