• 3.9 断点续传代码 > 我的程序猿之路:第二十九章


    断点续传全部代码

    JDK版本:JDK1.6

      TOMCAT:TOMCAT

    前端技术:

              webuploader

    jquery-1.7.2

    bootstrap

    所用jar/jdk包外:

    commons-fileupload-1.3.3.jar

    commons-io-2.5.jar

    servlet-api.jar/此包在tomcat

    目录结构:

     

     

    com/airodlcx/CheckChumServlet.java

    package com.airodlcx;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    
    
    //import org.apache.commons.beanutils.BeanUtils;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.FileUtils;
    
    /**
     * Servlet implementation class UploadVideo
     */
    public class CheckChumServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
    	/**
    	 * @see HttpServlet#HttpServlet()
    	 */
    	public CheckChumServlet() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    	 *      response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		response.getWriter().append("Served at: ").append(request.getContextPath());
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    	 *      response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    	
    		 String fileName = request.getParameter("fileName");  
    		 String fileMd5 = request.getParameter("fileMd5");    
    	        String chunk = request.getParameter("chunk");    
    	        String chunkSize = request.getParameter("chunkSize");  
    	        String guid = request.getParameter("guid");
    			
    	        String path = request.getSession().getServletContext().getRealPath("/upload");
    	        File checkFile = new File(path+"/"+guid+"/"+chunk);  
    	        
                response.setContentType("text/html;charset=utf-8");    
                //检查文件是否存在,且大小是否一致    
                if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){    
                    //上传过    
                    try {  
                        response.getWriter().write("{"ifExist":1}");  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }    
                }else{    
                    //没有上传过    
                    try {  
                        response.getWriter().write("{"ifExist":0}");  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }    
                }    
    	}
    }
    

    com/airodlcx/UploadSuccessServlet.java

    package com.airodlcx;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.io.FileUtils;
    
    
    public class UploadSuccessServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public UploadSuccessServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		response.getWriter().append("Served at: ").append(request.getContextPath());
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String path = request.getSession().getServletContext().getRealPath("/upload");
    
    		String guid = request.getParameter("guid");
    
    		String fileName = request.getParameter("fileName");
    		
    		System.out.println("start...!guid="+guid+";fileName="+fileName);
    		/**
    		 * 进行文件合并
    		 */
    		File file = new File(path+"/"+guid);
    
    		new File("C://upload"+"/"+guid).mkdirs();
    		/**
    		 * 进行文件合并
    		 */
    		File newFile = new File("C://upload"+"/"+guid+"/"+fileName);
    		FileOutputStream outputStream = new FileOutputStream(newFile, true);//文件追加写入
    		
    		byte[] byt = new byte[10*1024*1024];
    		int len;
    		FileInputStream temp = null;//分片文件
    		File[] childs = new File(path+"/"+guid).listFiles();
    		for(int i = 0 ; i<childs.length ; i++){
    			temp = new FileInputStream(childs[i]);
    			while((len = temp.read(byt))!=-1){
    				//System.out.println(len);
    				outputStream.write(byt, 0, len);
    			}
    		}
    		/**
    		 * 当所有追加写入都写完  才可以关闭流
    		 */
    		outputStream.close();
    		temp.close();
    
    		System.out.println("success!guid="+guid+";fileName="+fileName);
    		
    	}
    
    }
    

    com/airodlcx/UploadVideoServlet.java 

    package com.airodlcx;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    //import org.apache.commons.beanutils.BeanUtils;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.FileUtils;
    
    /**
     * Servlet implementation class UploadVideo
     */
    public class UploadVideoServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
    	/**
    	 * @see HttpServlet#HttpServlet()
    	 */
    	public UploadVideoServlet() {
    		
    		super();
    		System.out.println("------");
    		// TODO Auto-generated constructor stub
    	}
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    	 *      response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		System.out.println("request.getContextPath():"+request.getContextPath());
    		response.getWriter().append("Served at: ").append(request.getContextPath());
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    	 *      response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		System.out.println("===============================");
    		String path = request.getSession().getServletContext().getRealPath("/upload");
    		System.out.println(path);
    		DiskFileItemFactory factory = new DiskFileItemFactory();
    		// 2、创建一个文件上传解析器
    		ServletFileUpload upload = new ServletFileUpload(factory);
    		// 设置单个文件的最大上传值
    		upload.setFileSizeMax(15*1024*1024L);
    		// 设置整个request的最大值
    		upload.setSizeMax(15*1024*1024L);
    		// 解决上传文件名的中文乱码
    		upload.setHeaderEncoding("UTF-8");
    		// 3、判断提交上来的数据是否是上传表单的数据
    		if (!ServletFileUpload.isMultipartContent(request)) {
    			return;
    		}
    		// 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个
    		//List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
    		List<FileItem> list = null;
    		try {
    			list = upload.parseRequest(request);
    		} catch (FileUploadException e) {
    			e.printStackTrace();
    		}
    
    		HashMap<String, String> map = new HashMap<String, String>();
    		for (FileItem item : list) {
    			if (item.isFormField()) {
    				/**
    				 * 表单数据
    				 */
    				String name = item.getFieldName();
    				// 解决普通输入项的数据的中文乱码问题
    				String value = item.getString("UTF-8");
    				// value = new String(value.getBytes("iso8859-1"),"UTF-8");
    				System.out.println(name + "=" + value);
    				map.put(name, value);// 放入map集合
    			} else {
    				/**
    				 * 文件上传
    				 */
    				File fileParent = new File(path + "/" + map.get("guid"));//以guid创建临时文件夹
    				System.out.println(fileParent.getPath());
    				if (!fileParent.exists()) {
    					fileParent.mkdir();
    				}
    				String filename = item.getName();
    				if (filename == null || filename.trim().equals("")) {
    					continue;
    				}
    				// 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:
    				// c:a1.txt,而有些只是单纯的文件名,如:1.txt
    				// 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
    				filename = filename.substring(filename.lastIndexOf("\") + 1);
    				//创建文件
    				File file;
    				if (map.get("chunks") != null) {
    					file = new File(fileParent, map.get("chunk"));
    				} else {
    					file = new File(fileParent, "0");
    				}
    				//copy
    				FileUtils.copyInputStreamToFile(item.getInputStream(), file);
    			}
    		}
    	}
    }
    

     /upload/WebContent/index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base
    	href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
    <script type="text/javascript" src="upload/jquery-1.7.2.js"></script>
    <script type="text/javascript" src="upload/webuploader.min.js"></script>
    <link href="/upload/webuploader.css" type="css/text" />
    <script type="text/javascript" src="upload/jquery-2.0.0.min.js"></script>
    <script type="text/javascript" src="upload/jquery-ui.js"></script>
    <link href="upload/bootstrap.min.css" rel="stylesheet" media="screen">
    <script type="text/javascript" src="upload/bootstrap.min.js"></script>
    </head>
    <body>
    	
    	<h2>断点上传</h2>
    	<div style="margin: 20px 20px 20px 0;">
    		<div id="picker" class="form-control-focus">选择文件</div>
    	</div>
    	<div id="thelist" class="uploader-list"></div>
    	<button id="btnSync" type="button" class="btn btn-warning">开始同步</button>
    	
    	
    	<div class="progress">
    	  <div id="progress" class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style=" 0%;">
    	    <span class="sr-only">60% Complete</span>
    	  </div>
    	</div>
    	
    	
    	<script>
        var fileMd5;  //文件唯一标识  
        
        /******************下面的参数是自定义的*************************/  
        var fileName;//文件名称  
        var oldJindu;//如果该文件之前上传过 已经上传的进度是多少  
        var count=0;//当前正在上传的文件在数组中的下标,一次上传多个文件时使用  
        var filesArr=new Array();//文件数组:每当有文件被添加进队列的时候 就push到数组中  
        var map={};//key存储文件id,value存储该文件上传过的进度  
    	 WebUploader.Uploader.register({    
    	        "before-send-file":"beforeSendFile",//整个文件上传前  
    	        "before-send":"beforeSend",  //每个分片上传前  
    	        "after-send-file":"afterSendFile",  //分片上传完毕  
    	    },  
    	    {    
    	        //时间点1:所有分块进行上传之前调用此函数    
    	        beforeSendFile:function(file){  
    	        	//alert('----');
    	            var deferred = WebUploader.Deferred();    
    	            //1、计算文件的唯一标记fileMd5,用于断点续传  如果.md5File(file)方法里只写一个file参数则计算MD5值会很慢 所以加了后面的参数:10*1024*1024  
    	            (new WebUploader.Uploader()).md5File(file,0,10*1024*1024).progress(function(percentage){  
    	                $('#'+file.id ).find('p.state').text('正在读取文件信息...');  
    	            })    
    	            .then(function(val){    
    	                $('#'+file.id ).find("p.state").text("成功获取文件信息...");    
    	                fileMd5=val;    
    	                uploader.options.formData.guid = fileMd5;
    	                console.log("fileMd5:"+fileMd5);
    	                //获取文件信息后进入下一步    
    	                deferred.resolve();    
    	            });    
    	              
    	            fileName=file.name; //为自定义参数文件名赋值  
    	            return deferred.promise();    
    	        },    
    	        //时间点2:如果有分块上传,则每个分块上传之前调用此函数    
    	        beforeSend:function(block){  
    	        	//alert('-******-');
    	            var deferred = WebUploader.Deferred();    
    	            $.ajax({    
    	                type:"POST",    
    	                url:"${ctx}/upload/CheckChumServlet",  //ajax验证每一个分片  
    	                data:{    
    	                    fileName : fileName,  
    	                    fileMd5:fileMd5,  //文件唯一标记    
    	                    chunk:block.chunk,  //当前分块下标    
    	                    chunkSize:block.end-block.start,//当前分块大小  
    	                    guid: uploader.options.formData.guid
    	                },    
    	                cache: false,  
    	                async: false,  // 与js同步  
    	                timeout: 1000, //todo 超时的话,只能认为该分片未上传过  
    	                dataType:"json",    
    	                success:function(response){    
    	                	console.log(block.chunk+"--"+response.ifExist);
    	                    if(response.ifExist){  
    	                        //分块存在,跳过    
    	                        deferred.reject();    
    	                    }else{    
    	                        //分块不存在或不完整,重新发送该分块内容    
    	                        deferred.resolve();    
    	                    }    
    	                }    
    	            });    
    	                               
    	            this.owner.options.formData.fileMd5 = fileMd5;    
    	            deferred.resolve();    
    	            return deferred.promise();    
    	        },    
    	        //时间点3:所有分块上传成功后调用此函数    
    	        afterSendFile:function(){  
    	        	//alert('-***2222**-');
    	            //如果分块上传成功,则通知后台合并分块    
    	            $.ajax({    
    	                type:"POST",    
    	                url:"${ctx}/mergeOrCheckChunks.do?param=mergeChunks",  //ajax将所有片段合并成整体  
    	                data:{    
    	                    fileName : fileName,  
    	                    fileMd5:fileMd5,  
    	                },    
    	                success:function(data){  
    	                    count++; //每上传完成一个文件 count+1  
    	                    if(count<=filesArr.length-1){  
    	                        uploader.upload(filesArr[count].id);//上传文件列表中的下一个文件  
    	                    }  
    	                     //合并成功之后的操作  
    	                }    
    	            });    
    	        }    
    	    }); 
    		var uploader = WebUploader.create({
    
    			// swf文件路径
    			swf : 'webuploader/Uploader.swf',
    			// 文件接收服务端。
    			server : 'UploadVideoServlet',
    			// 选择文件的按钮。可选。
    			// 内部根据当前运行是创建,可能是input元素,也可能是flash.
    			pick : '#picker',
    			chunked: true,  //分片处理
                chunkSize: 10 * 1024 * 1024, //每片5M  
                threads:3,//上传并发数。允许同时最大上传进程数。
    			// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
    			resize : false
    		});
    
    		// 当有文件被添加进队列的时候
    		uploader.on('fileQueued', function(file) {
    			//alert(123);
    			$("#thelist").append(
    					'<div id="' + file.id + '" class="item">'
    							+ '<h4 class="info">' + file.name + '</h4>'
    							+ '<p class="state">等待上传...</p>' + '</div>');
    		});
    
    		uploader.on('uploadProgress', function(file,percentage) {
    			$("#progress").css("width",parseInt(percentage*100)+"%");
    		});
    		
    		uploader.on('uploadSuccess', function(file) {
    			$('#' + file.id).find('p.state').text('已上传');
    			$.post("UploadSuccessServlet", { "guid": uploader.options.formData.guid,fileName:file.name},
    			   function(data){
    		   	}, "json");
    		});
    
    		uploader.on('uploadError', function(file) {
    			$('#' + file.id).find('p.state').text('上传出错');
    		});
    
    		uploader.on('uploadComplete', function(file) {
    			$('#' + file.id).find('.progress').fadeOut();
    		});
    		
            uploader.on( 'beforeFileQueued', function( file ) {
                
             // alert(file.size);
    
            }); 
    
    		$("#btnSync").on('click', function() {
    			if ($(this).hasClass('disabled')) {
    				return false;
    			}
    			console.log("get fileMd5:"+fileMd5);
    			
    			uploader.upload();
    
    		});
    	</script>
    </body>
    </html>
    

    WebContent/WEB-INF/web.xml  

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>upload</display-name>

    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:viewSpace.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
    <description></description>
    <display-name>UploadVideoServlet</display-name>
    <servlet-name>UploadVideoServlet</servlet-name>
    <servlet-class>com.airodlcx.UploadVideoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>UploadVideoServlet</servlet-name>
    <url-pattern>/UploadVideoServlet</url-pattern>
    </servlet-mapping>
    <servlet>
    <description></description>
    <display-name>UploadSuccessServlet</display-name>
    <servlet-name>UploadSuccessServlet</servlet-name>
    <servlet-class>com.airodlcx.UploadSuccessServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>UploadSuccessServlet</servlet-name>
    <url-pattern>/UploadSuccessServlet</url-pattern>
    </servlet-mapping>


    <servlet>
    <description></description>
    <display-name>CheckChumServlet</display-name>
    <servlet-name>CheckChumServlet</servlet-name>
    <servlet-class>com.airodlcx.CheckChumServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>CheckChumServlet</servlet-name>
    <url-pattern>/CheckChumServlet</url-pattern>
    </servlet-mapping>

    </web-app>

    -------------------------------------------------------------------------------------这段代码可以改一改加上----------------------------------------------------------------------------------------------------------

     function check() {
                var fileInput = $("#AddFiles_myFile");
                var fileName = fileInput.val().trim();
                if (fileName == '') {
                    alert("请选择要上传的文件");
                    return false;
                }
                if (fileName.indexOf('#') >= 0) {
                    alert('文件名中不能有井号');
                    return false;
                }
                if (fileName.indexOf('+') >= 0) {
                    alert('文件名中不能有加号');
                    return false;
                }
                if (fileName.indexOf(' ') >= 0) {
                    alert('文件名中不能有空格');
                    return false;
                }
                var reg = /(.zip|.rar|.js|.css|.xml|.7z|.ico|.pdf|.ppt|.pptx|.xap|.xpi|.swf|.apk|.cdf|.gif|.tar|.gz|.sh|.bmp)$/ig;
                if (!reg.test(fileName)) {
                    var supportType = reg.toString().replace(//|(|)|\|/ig, '');
                    supportType = supportType.substring(0, supportType.length - 3);
                    supportType = supportType.replace(/|/g, ' ');
                    alert('不支持该上传文件类型!
    支持的文件类型:' + supportType);
                    return false;
                }
                if (fileInput.length
                    && fileInput[0].files.length
                    && fileInput[0].files[0].size > 10*1024*1024)
                {
                    alert('上传文件大小不能超过' + 10 + 'MB');
                    fileInput.val('');
                    return false;
                }            
                return true;
            }
    

      

  • 相关阅读:
    解决DataGridView绑定List后不能排序的问题
    最新的皮肤下载
    我收录的名言
    HttpRequest访问Https带有证书并使用WSDL文档生成代理类方案(2)
    最新的Functions 类
    华兴软通短信接口简单使用WebServices版
    最新的SqlHelper 类
    闲来没事写个记事本玩玩!!!
    "基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系"证书验证失败的解决过程(3)
    FCK配置
  • 原文地址:https://www.cnblogs.com/fanyuyi-boke/p/qiao_duo_shao_nian_dai_ma_neng_ba_shou_zhi_mo_ping29.html
Copyright © 2020-2023  润新知