文档章节

基于hessian的文件传输 (转)

liangyx
 liangyx
发布于 2012/07/20 17:29
字数 624
阅读 3429
收藏 6

基于hessian的文件传输

通常文件传输建议还是通过 ftp ,只有当 ftp 满足不了需求时,才考虑 hessian 的传输方案。

Hessian 传文件的应用场景有比如两台需要传输文件的服务器之间的网络情况限制比较严格,不允许 ftp 或新开端口之类;两台服务器之间传文件必须经过一台中间机器中转。还有就是获得比 ftp 传输更大的灵活性。上面的一些应用场景,都是在项目里实际遇到的。

Hessian 是不支持 File 的直接传输的,所以采取的方案是将 File 读到 byte[] 再用 hessian 传输。
  
不过最新的
 hessian4.0 已经支持 InputStream 作为参数或返回值进行传输。

说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif    public  String uploadStream(String filename, InputStream data)
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif    
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif        HessianInerface hessianInerface 
 =  (HessianInerface) getHessianInterface();
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif        
 return  hessianInerface.uploadStream(filename, data);
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif    }


但是以上2中方法都会有个问题,就是当文件比较大的时候,会报java.lang.OutOfMemoryError

基于 byte[] 的方法的解决办法是将大的文件分成一小块一小块进行传输。

说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif   public  String uploadSingleFiles(File file)
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif    
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif        String logicPath 
 =   "" ;
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif        InputStream is 
 =   null ;
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif        
 try 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif         
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            
 byte [] buffer  =   null ;
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            HessianInerface hessianInerface 
 =  (HessianInerface) getHessianInterface();
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            is 
 =   new  FileInputStream(file);
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            
 long  size  =  file.length();
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            
 long  perSize  =  onePerSize;
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            
 if  (size  >  onePerSize)
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif            
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                
 long  index  =  size  /  perSize;
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                
 if  (size  >  perSize  *  index)
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif                
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                    index 
 =  index  +   1 ;
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif                }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                
 for  ( long  j  =   1 ; j  <=  index; j ++ )
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif                
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                    
 long  curPerSize  =  perSize;
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                    
 if  (j  ==  index)
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif                    
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                        curPerSize 
 =  size  -  perSize  *  (j  -   1 );
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif                    }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                    buffer 
 =   new   byte [( int ) curPerSize];
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                    is.read(buffer);
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                    
 if  (j  ==   1 )
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif                    
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                        logicPath 
 =  hessianInerface.uploadSingleBigFile(buffer,
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                                file.getName(), 
 false );
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif                    }
   else 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif                     
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                        logicPath 
 =  hessianInerface.uploadSingleBigFile(buffer,
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                                file.getName(), 
 true );
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif                    }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif                }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif            }
   else 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif             
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                buffer 
 =   new   byte [is.available()];
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                is.read(buffer);
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                logicPath 
 =  hessianInerface.uploadSingleFile(buffer, file
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif                        .getName());
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif            }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif        }
   catch  (IOException e)
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif        
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            
 throw   new  RuntimeException(e);
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif        }
   finally 
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif         
 {
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif            IOUtils.closeQuietly(is);
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif        }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif        
 return  logicPath;
说明: http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif    }
 
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif



基于 InputStream 的解决办法,最初想法讲 InputStream 分块读出传输,不过没成功,如果谁成功,请告诉我一声。

总结,如果 jvm 的内存设置比较大, InputStream 的方式是可以直接传输的,而 byte[] 的方式超过一定的大小就报错,在我的机器上大概 20M 左右。所以基于 byte[] 的分块传输是目前比较合理的解决办法。

代码比较多,我就不一一帖出了,在最后放出下载的链接,在服务端的实现类请根据自己的需求稍微修改下就能运行起来。

使用方法示例如下 :

说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif HessianClient cl  =   new  HessianClient();
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif cl.setHessianserviceurl(
 http://127.0.0.1:80/hessianService );
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif            
 long  onePerSize  =   2080000 ;
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif          cl.setOnePerSize(onePerSize);
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif         File file1 
 =   new  File( " d:\\tddownload\\CJT.rar " );
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif        cl.uploadSingleFiles(file1)  ;
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif 
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif        File ff
 =    cl.downloadSingleBigFile( 23884L , " 中文9999.rar " )  ;
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif
说明: http://www.blogjava.net/Images/OutliningIndicators/None.gif

 

代码还可以继续完善的地方,比如加入文件的完整性校验,压缩传输等。
代码下载地址:
http://www.blogjava.net/Files/magicdoom/hessianTransferFile.rar

 

本文转载自:

liangyx

liangyx

粉丝 15
博文 35
码字总数 6511
作品 0
广州
程序员
私信 提问
加载中

评论(1)

马文夕
马文夕
赞一个...13
WebService另一种轻量级实现—Hessian 学习笔记

最近研究,得知他们在使用一种叫做Hessian的WebService实现方式实现远程方法调用,是轻量级的,不依赖JavaEE容器,同时也是二进制数据格式传输,效率比SOAP的XML方式要高。感觉像是RESTFUL方...

商者
2016/03/29
45
0
简单的Hessian接口开发实例

需要的jar包 hessian-4.0.7.jar #客户端 接口 package com.test; public interface Printer { public String print(String a); public String say(); } 2.实现该接口 package com.test; publ......

阿联酋挖石油
2015/08/04
171
0
Hessian通信协议学习

什么是Hessian   Hessian是由caucho提供的一种开源的远程通讯协议。 Hessian协议工作流程图   *客户端程序请求服务端函数 *   1.调用客户端句柄,执行传送参数。   2.调用本地系统内...

o0无忧亦无怖
2015/10/15
366
0
Dubbo服务 上传文件解决方案以及Hessian协议

协议支持 Dubbo支持多种协议,如下所示: Dubbo协议 Hessian协议 HTTP协议 RMI协议 WebService协议 Thrift协议 Memcached协议 Redis协议 在通信过程中,不同的服务等级一般对应着不同的服务质...

摘星族
01/22
0
0
Dubbo面试20问!这些题你都遇到过吗?

作者:Dean Wang https://deanwang1943.github.io/bugs/2018/10/05/面试/饿了么/dubbo 面试题/ 1、dubbo是什么 dubbo是一个分布式框架,远程服务调用的分布式框架,其核心部分包含: 集群容错...

安小乐
06/10
67
0

没有更多内容

加载失败,请刷新页面

加载更多

怎样在磁盘上查找MySQL表的大小?这里有答案

我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎。不应该在 INFORMATION_SCHEMA.TABLES 中提供这些信息吗?没那么简单! 我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎。不应...

Linux就该这么学
41分钟前
5
0
Redis

一、Redis支持的几种数据类型:字符串、List、SET、HASH、ZSET 二、Redis的缓存技术主要是为了降低关系数据库的负载并减少网站成本 三、在Redis里面,被MULTI命令和EXEC命令包围的所有命令会...

BobwithB
43分钟前
4
0
MongoDB基础之入门

MongoDB基础之入门 一、MONGODB简介 MongoDB由C/C++开发,是一种强大、灵活、可扩展的数据存储方式。它扩展了关系型数据库的众多有用功能,例如:辅助索引、范围查询和排序。MongoDB还内置了...

星汉
45分钟前
7
0
c++ 神奇的赋值用法

c++ 神奇的赋值用法(第8章)

天王盖地虎626
今天
5
0
Jquery操作UI之设置字体大小

先获取字体大小,进行处理。再将修改的值保存。 slice() 方法可从已有的数组中返回选定的元素。 arrayObject.slice(start,end)。 start 必需。规定从何处开始选取。如果是负数,那么它规定从...

前端老手
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部