zoukankan      html  css  js  c++  java
  • 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);
    		}
    		
    		
    	}
    
    	
    }
    

      

    目录如下:

  • 相关阅读:
    ASP.NET中的DataBinder.Eval用法
    jquery Ajax调用asmx和ashx代码示例三级联动
    项目中使用的架构
    asp.net(c#)上传图片到数据库
    asp.net(c#)从数据库里读取图片并显示到页面
    一款好的UI草图设计软件
    Windows Azure云平台(无须提供信用卡)[转]
    推荐8个超棒的学习 jQuery 的网站
    推荐两个界面原型设计工具GUIDesignStudio 和 Mockups For Desktop
    在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)
  • 原文地址:https://www.cnblogs.com/achengmu/p/10974808.html
Copyright © 2011-2022 走看看