关闭

stream插件跨域大文件断点续传实战+自定义限速

标签: ssh断点续传大文件上传stream
2656人阅读 评论(4) 收藏 举报
分类:
JAVA跨域大文件断点续传+自定义限速

前言:本文所讲到的内容完全独创,遇坑很多,但是本着资源共享的原则,将两个星期的成果分享给大家,请尊重别人的劳动成果,转载请注明出处:http://blog.csdn.net/qq_27063119,谢谢!

先讲述一下本文所针对的问题:
1.跨域,所谓跨域就是就是服务器之间的分离,如,一个系统中,应用程序为在一个服务器上,而应用程序往往需要上传文件,将上传文件作为独立的一个功能放在另外的一台服务器上,这时上传文件就是跨域了,若将上传文件部分也放在应用服务器上,一旦流量过大,服务器瘫痪,那么会导致主应用程序也不能够使用。

2.大文件断点续传 , 这是基于HTML5标准,因此IE9(包括IE9)以下浏览器不支持,为了兼容了IE6以上的浏览器上传,只能选择使用flash进行上传,但是此时不可以断点续传。

3.自定义限制文件上传的速度  ,对源码进行修改时的支持自定义限速功能。


(第一种)以下为简单整合上传的方法(不跨域可以使用):
    这里我们借助了stream上传插件,这是官网:http://www.twinkling.cn  ,然后点击下载页,通过开源中国或者百度云盘下载官方的实例1.8.1.xxx,需要下载stream-1.8.1.10157.war,以及stream-1.8.0.10076-r.jar,官方的JAVA后台代码jiangdx-stream-master.zip只有从开源中国上面下载,准备好这两个文件就可以了,开始整合操作:
(1).解压jiangdx-stream-master.zip文件后,将jiangdx-stream-master\stream\src\main文件夹下的java目录整个拷贝到你的项目src中。

(2)解压stream-1.8.1.10157.war后,打开文件夹,将除了META-INF ,WEB-INF不拷贝其他全部拷贝到自己工程项目的WEB-INF目录下.

(3).添加jar包,将stream-1.8.1.10157\WEB-INF\lib 下的所有jar包以及stream-1.8.0.10076-r.jar,json-20090211.jar拷贝放置到自己工程的lib下
    到这里基本最简单的文件上传就搭建好了,打开tomcat服务器,浏览器输入地址,http://127.0.0.1:8080/stream/index.html,进入上传页面,即可进行文件上传,这是官方的指导方法,实际上按照上面的做法并不能进行上传,至少IE还是不能进行上传,这里说一下解决的方法:
  a:    修改url地址
swfURL : "/swf/FlashUploader.swf", 改为相对地址:swfURL : "swf/FlashUploader.swf", 
tokenURL : "/tk",改为相对地址:tokenURL : "tk",
frmUploadURL : "/fd", 改为相对地址:frmUploadURL : "fd",
uploadURL : "/upload", 改为相对地址:uploadURL : "upload",
 
  b:   最后一个参数结尾不要加逗号
     var config = {
    .....第一个参数......,
    ......第二个参数..... ,
    ......第N个参数......
}
注意最后一个参数不要以,号结尾,否则IE下就不能执行了。
以上修改好后即可进行上传操作,文件保存的路径在 stream-config.properties 配置中。

  虽然以上配置好了可以进行上传操作,但是远远不能满足公司实际使用的要求,比如防止文件冲突,对上传的文件进行重命名操作同时保存实际文件名至数据库,配置数据库连接池,上传限速,应用上传分离中的跨域上传,于是这里是本人原创的做法,不一定就是最好的,但是可以借鉴使用。 这里采用了spring MVC  + spring  + hibernate  + stream插件进行整合在一起。

(第二种 )修改后具有的特点:SSH框架整合,文件防冲突,回传文件信息至前台,上传界面美化,上传限速,跨域上传,兼容IE6-IE9 :

为了让大家更好的了解这个上传问题,这里贴出了我的代码地址:http://download.csdn.net/detail/qq_27063119/9630240  (6个金币下载,大家支持一下好吧,打这么多字不容易啊,实在没有金币就  至我邮件  nuohy@qq.com(不一定能够及时回复,请谅解!))

(1)首先还是搭建好上传文件的项目以支持跨域上传,使用spring MVC+spring+hibernate的框架,以及一个测试的项目(随便用什么搭建,建议使用最简单的jsp+servlet),搭建完毕后,效果是,启动两个项目,当然两个项目可以放置到两台机器上,只要两台机器可以ping通就可以,

streamSH项目结构如图所示:




ceshi项目结构如图所示:



看了上面的结构,大家应该有所了解了吧,其中streamSH中的TokenController可以去掉,因为跨域上传,token码是由应用服务器生成的,所以要放到ceshi项目中。当然stream有自己的配置文件文档上说可以进行跨域上传,但是我试了好久发现不好用,于是自己改写了,在streamSH项目上加了过滤器进行添加头信息

public class SecurityFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response, FilterChain chain)throws ServletException, IOException {
System.out.println("********************跨域**********************");
System.out.println("=========="+request.getMethod()+"============"+request.getHeader("Access-Control-Request-Method"));
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
System.out.println("===================添加头文件===================");
response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Range,Content-Type");
            response.addHeader("Access-Control-Max-Age", "1800");//30 min
        }
chain.doFilter(request, response);
    }
}



并且每个controller都会对request以及response进行添加头信息 即在controller中调用doOptions()方法

@RequestMapping(method=RequestMethod.GET,value="/upload")
	public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException{
	doOptions(req, resp);
	.
	.
	.
}


protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException{
	req.setCharacterEncoding("UTF-8");
	resp.setCharacterEncoding("UTF-8");
	resp.setContentType("application/json;charset=utf-8");
	resp.setHeader("Access-Control-Allow-Origin", "*");
	resp.setHeader("Access-Control-Allow-Headers", "Content-Range,Content-Type");
	resp.setHeader("Access-Control-Allow-Origin", Configurations.getCrossOrigins());
	resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
}



(2)上传界面美化,如下图所示,这里我改动了js以及css样式以及iframe的界面,具体可以参考我的代码,



 这里顺带提一下,测试跨域上传时候,如果两个项目放在本机同一个服务器下,建议使用http://127.0.0.1:8080 开头或者  http://localhost:8080,不然即使不能够跨域上传,但是测试不出来,

(3)上传限速问题
      其实限速原理很简单,也就是while循环写入数据时候,加上Thread.sleep(XXX);就达到了限速目的,这里我在配置文件中加了一句   STREAM_UPLOAD_SPEED=1500   (及1.5MB/S),  后台拿到这个数据后,需要进行操作,
 真正的休眠时间为:7500/(STREAM_UPLOAD_SPEED数字);   这个是我的机器测试测出来的,可以自行计算填写的,然后flax上传时,休眠时间为  (7500/(STREAM_UPLOAD_SPEED数字))/2,不要问为什么,我也是测出来的。

(4)兼容IE6-IE9
    为了兼容IE6-IE9,需要使用flash进行上传,当然不跨域时候比较容易的,跨域了,就会麻烦,比如:IE7跨域上传时候,tolenURL  必须为应用服务器的controller或者servlet的地址,否则上传不了,这里弄好了过后,你会发现还是上传不了的,因为flash跨域时候会请求跨域服务器的crossdomain.xml文件,这个文件要放到 tomcat的根目录下,也就是webapps\ROOT目录下,如果发现没有这个目录,那你应该是使用myeclipse了,这里举个例子:放到workspace\.metadata\.me_tcat7\webapps目录下  ,然后在server.xml的<Host></Host>中添加
<Context path="" docBase="D:\\myeclipse\\workspace\\.metadata\\.me_tcat7\\webapps\\" reloadable="true"  />
这样一段话即可,  不管你怎样弄,只要能够使保证用文件服务器的地址 加上crossdomain.xml,如http://192.168.1.141:8080/crossdomain.xml 能够访问到文件就可以了。这里一定要注意啊!!!!!



(5)文件防止冲突
因为用户上传的文件可能会重名,那么直接存储会导致覆盖文件,为了避免文件上传的冲突,于是我们要使用UUID对文件进行重新命名,并且将文件的真实名字以及UUID,文件路径都存储到数据库中,同时将UUID 以及 文件真实的名字 回传到前台,前台接受数据 通过
onComplete : function(file) {

}   //每次上传成功一个文件后都会调用
函数进行接收的,所有自定义返回的参数都放在了msg中,如下所示可以取出name和uuid的值。
var msg = eval("(" + file.msg + ")");
console.info(msg.map.name+"    "+msg.map.uuid);

这里还要说一点,先前我是将文件直接缓存到当前年月日的目录下,这样可以降低服务器在移动文件损耗的性能,但是后来发现,如果用户上传的文件过大,跨过了晚上12点,因为是分段上传的,12点后上传的文件会放置到新的年月日文件夹中,那么则会出现12点后的文件衔接不上12点之前上传的部分文件了, 这样会导致失败,
于是后来牺牲了性能,将所有上传的文件先都缓存在一个固定目录下,然后上传完毕后移动到当前的年月日文件夹下。不一定是好的办法,暂时这样用了。

为了让大家更好的了解这个上传问题,这里贴出了我的代码地址:http://download.csdn.net/detail/qq_27063119/9630240  (6个金币下载,大家支持一下好吧,打这么多字不容易啊,实在没有金币就  至我邮件  nuohy@qq.com(不一定能够及时回复,请谅解!))

到这里基本就讲完了,谢谢大家!!!


2
0
查看评论

上传文件获取Stream的方法

文件上传到服务器以后,需要取出流,比如说NPOI读取的时候要传入一个流。 方法一:上传之后,保存到服务器,然后通过路径读取文件; System.Web.HttpPostedFile postFile = null; postFile = FileUpload1.PostedFile; ...
  • wzj0808
  • wzj0808
  • 2016-05-11 13:28
  • 1247

stream插件上传文件

  • 2016-10-25 16:44
  • 143KB
  • 下载

支持文件夹上传的Stream插件

Stream 上传插件 Stream 是解决不同浏览器上传文件的插件,是Uploadify的Flash版和Html5版的结合! Stream 简介 Stream 是根据某网的文件上传插件加工而来,支持不同平台(Windows, Linux, Mac, Android, iOS)下,...
  • rain_man_happy
  • rain_man_happy
  • 2014-01-14 13:58
  • 4680

WebUploader插件上传大文件单文件和多文件JAVA版使用总结

Webuploader 单文件,多文件 多实例 使用范例
  • New_sara
  • New_sara
  • 2016-06-07 16:57
  • 34018

使用stream_context_create远程上传文件

使用stream_context_create发送远程流文件
  • u013672759
  • u013672759
  • 2016-01-27 18:06
  • 724

跨域的几种办法原理详细

1、什么是跨域 获取一个页面的域: document.domain;// qianduanblog.com 为了页面和服务器的安全(?),脚本是不能访问非本域的动态网络资源,但可以访问如脚本、样式、图片、视频、音频等这些静态资源。 那什么是跨域呢?存在以下情况中之一,即发生跨域: 网络...
  • wuliyun88
  • wuliyun88
  • 2016-01-15 10:56
  • 1962

支持断点续传的多文件上传开发控件

    应用iWebFile2005控件,能够非常方便的开发多文件上传,  支持大文件上传(大于50M以上)和断点续传的程序.下载地址: http://www.goldgrid.com/Products/CView.asp?id=82客户端程序...
  • csdnhome
  • csdnhome
  • 2005-01-12 11:38
  • 3815

JQuery上传插件 HTML5 upload断点续传上传插件

HTML5upload(http://www.html5upload.com)是基于html5技术的,由jquery把上传逻辑封装起来的支持断点续传上传jquery插件。无需安装任何插件,只要浏览器支持html5技术即可实现断点续传上传。同时本软件支持跨域上传,支持获取本地文件的md5值,在上传后可...
  • onetwofree
  • onetwofree
  • 2017-05-21 00:02
  • 1069

Web大文件断点续传,快来看看吧!

UselessProgrammer 2016-11-21 17:28 相信很多像我一样的好学的工程师对web的大文件的断点续传都有点儿兴趣,那么今天我们一起来动手实现它. 作为开始,我们先简单了解一下为什么要做断点续传: 传统方式的缺点: 大文件上传往往比较耗时,如果采用...
  • u011277123
  • u011277123
  • 2016-11-22 09:42
  • 3900

Stream断点续传插件

  • 2016-09-01 17:20
  • 218KB
  • 下载
    个人资料
    • 访问:44613次
    • 积分:851
    • 等级:
    • 排名:千里之外
    • 原创:40篇
    • 转载:3篇
    • 译文:0篇
    • 评论:23条
    最新评论