大文件上传----webuploader分片上传

参考:https://www.zhangshengrong.com/p/O3aAyoKa4E/

https://www.jianshu.com/p/1fab52f45fb3

https://blog.csdn.net/u014150463/article/details/74044467/

https://www.cnblogs.com/hackxiyu/p/8203400.html

https://blog.csdn.net/qq_34698126/article/details/54429721#

webuploder API:http://fex.baidu.com/webuploader/doc/#WebUploader_Uploader_upload

需求:上传大文件资源以及一些基础信息存储到数据库
 大文件上传----webuploader分片上传_第1张图片

实现思路:分为2大步:

一:通过webuploader前端插件分页上传到服务器,服务器合页

二:上传完成,设置文件字段名称,再普通表单提交,存储信息到数据库

难点:一步具体实现:

前端页面——分页上传:

1,导入webuploader的css,js文件

大文件上传----webuploader分片上传_第2张图片

ps:使用webuploader插件,必须要导入的文件:如果没有jq.js会报错:Uncaught ReferenceError: WebUploader is not defined     at (index):46 (anonymous) @ (index):46

 大文件上传----webuploader分片上传_第3张图片

2,文件上传组件: 

 大文件上传----webuploader分片上传_第4张图片

 3,js函数:

    

因为前端文件时分片上传,webuploader根据 设定的 chunkSize: 1024 * 1024 * 100,   //每一片的大小100M,将文件分片,按片上传访问服务器,服务器接收到每片后:将每片标号存储再一个临时文件中,当所有分片都访问了服务器,就按顺序进行写操作:

 

4.后端 

/*
	 * 上传文件
	 */
	@RequestMapping("/fileupload")
	@ResponseBody
	public void fileupload(HttpServletRequest request,Model model) throws IOException{
		 
		
		try {
		//1、创建磁盘文件项工厂
		//作用:设置缓存文件的大小  设置临时文件存储的位置
		String path_temp = request.getSession().getServletContext().getRealPath("temp");
		//DiskFileItemFactory factory = new DiskFileItemFactory(1024*1024, new File(path_temp));
		//1、创建磁盘文件项工厂--一些相关的配置的设置  缓存的大小 临时目录的位置
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(1024*1024);
		factory.setRepository(new File(path_temp));
	
		//2、创建文件上传的核心类
		ServletFileUpload upload = new ServletFileUpload(factory);
		//设置上传文件的名称的编码
		upload.setHeaderEncoding("UTF-8");

		//ServletFileUpload的API
		boolean multipartContent = upload.isMultipartContent(request);//判断表单是否是文件上传的表单
		
		if(multipartContent)
		{
			//是文件上传的表单
				//***解析request获得文件项集合,每一个FileItem对应一个Form表单的输入项
	
				List parseRequest;
				
					parseRequest = upload.parseRequest(request);
					 String id = ""; 
				        String fileName = ""; 
				        // 如果大于1说明是分片处理 
				        int chunks = 1; 
				        int chunk = 0; 
				        FileItem tempFileItem = null;
					if(parseRequest!=null)
					{
						for(FileItem fileItem : parseRequest)
						{  if (fileItem.getFieldName().equals("id")) { 
				            id = fileItem.getString(); 
				          } else if (fileItem.getFieldName().equals("name")) { 
				            fileName = new String(fileItem.getString().getBytes("ISO-8859-1"), "UTF-8"); 
				          } else if (fileItem.getFieldName().equals("chunks")) { 
				            chunks = Integer.parseInt(fileItem.getString()); 
				          } else if (fileItem.getFieldName().equals("chunk")) { 
				            chunk = Integer.parseInt(fileItem.getString()); 
				          } else if (fileItem.getFieldName().equals("file")) { 
				            tempFileItem = fileItem; 
				          } 
						}
							System.out.println(id+" filename:"+fileName+"chunks:"+chunks+" chunk:"+chunk+" tempFileItem:"+tempFileItem);
							//通过读取配置文件,获得文件上传的目标地址
							Properties properties = new Properties();
							InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("resource/fileAddress.properties");  
							properties.load(inputStream);  
							String path_store = properties.getProperty("address");
							//System.out.println(path_store);
							//前端将上传的文件分片,然后每个分片访问服务器,每次分片访问服务器时,将分片的文件存放在临时文件夹里,当分片全都存储了,再合并分片
							//将上传文件内容写在指定文件夹下
							// 临时目录用来存放所有分片文件 
					        String tempFileDir = path_store + id; 
					        File parentFileDir = new File(tempFileDir); 
					        if (!parentFileDir.exists()) { 
					          parentFileDir.mkdirs(); 
					        } 
					     // 分片处理时,前台会多次调用上传接口,每次都会上传文件的一部分到后台 .
					        //将上传的一部分文件写到临时的文件夹下
					        File tempPartFile = new File(parentFileDir, fileName + "_" + chunk + ".part"); 
					        FileOutputStream out =new FileOutputStream(tempPartFile);
					        InputStream in = tempFileItem.getInputStream();
					        IOUtils.copy(in, out);
					        in.close();
							out.close();
							// 是否全部上传完成 
					        // 所有分片都存在才说明整个文件上传完成 
					        boolean uploadDone = true; 
					        for (int i = 0; i < chunks; i++) { 
					        //  File partFile = new File(parentFileDir, fileName + "_" + i + ".part"); 
					        	File partFile = new File(parentFileDir, fileName + "_" + i + ".part"); 
					          if (!partFile.exists()) { 
					            uploadDone = false; 
					          } 
					        } 
					     // 所有分片文件都上传完成 ,将所有分片文件合并到一个文件中
					        if (uploadDone) { 
					            // 得到 destTempFile 就是最终的文件 
					           File destTempFile = new File(path_store, fileName); 
					           for (int i = 0; i < chunks; i++) 
					           {
					        	   //遍历"所有分片文件"到"最终文件"中 
					             //将上传文件内容写在指定文件夹下
									
					        	   File partFile = new File(parentFileDir, fileName + "_" + i + ".part"); 
									//OutputStream destTempfos = new FileOutputStream(path_store+"/"+fileName);
					        	   FileOutputStream destTempfos = new FileOutputStream(destTempFile, true); 
									InputStream partin = new FileInputStream(partFile);
									IOUtils.copy(partin, destTempfos);
									partin.close();
									destTempfos.close();
					        
					             } 
					        
					           // 删除临时目录中的分片文件 
					           FileUtils.deleteDirectory(parentFileDir); 
					         
					          
					        }
					        
					        
					}
			}
				} catch (FileUploadException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			
		
		
	}

 这样就完成了大文件的分片上传

ps:当上传10G以上大文件,出现问题。原因:因为webuploader有超时时间,默认:webuploader的默认的超时时间是:2 * 60 * 1000。上传时间大于了超时时间,会重新上传导致错误。

参考:http://www.codingwhy.com/view/841.html

解决:设置超时时间为:0

待解决:断点续传,以及秒传。。。。。

 

你可能感兴趣的:(ssm,文件上传)