基于spring的mutipartFile实现上传功能:
1、前端表单上传文件(单个用MultipartFile,多个用MultipartFile[])
2、后台接收该请求中的multipartFile文件流
3、创建本地文件file
4、将multipartFile文件流转换到文件file中 = multiFile.transferTo(file);
5、将对应的javaBean文件对象信息,持久化到数据库中。


下载单个文件功能:
1、通过前端传入的文件对象id,获取到DB中的文件路径
2、设置响应信息:
    1)文件类型:response.setContentType("multipart/form-data");
    2)响应头及客户端保存文件名:response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")或者new String(fileName.getBytes("utf-8"), "ISO8859-1"));
    3)
3、创建BufferInputStream读取文件
4、响应中取出输出流,将输入流文件写入输出流。


下载多个文件功能:
1、获取前端传入的id数组,获取到DB中的文件路径
2、创建一个临时压缩包文件
3、将本地的多个文件,存入该压缩包中
4、设置响应信息:
    1)response.setContentType("application/octet-stream"); //设置内容类型为下载类型  
    2)response.setHeader("Content-disposition", "attachment;filename="+URLEncoder.encode(downLoadZipName, "UTF-8"));//设置下载的压缩文件名称
5、获取响应中的输出流,输入流读取临时压缩包文件,并写入输出流中。


附上部分下载实现代码:

//IO流实现下载的功能
/*
1、获取前端传来的文件id,并从数据库中获取到该文件全路径,再获取文件本地路径filePath(通常本地路径=自己设置的本地存储父路径+数据库文件全路径)
2、可根据filePath先创建文件对象,判断本地是否存在
.
.
.
*/
//响应信息设置  
res.setContentType("text/html; charset=UTF-8"); //设置编码字符  
res.setContentType("application/octet-stream"); //设置内容类型为下载类型  
res.setHeader("Content-disposition", "attachment;filename="+fileName);//设置下载的文件名称  
OutputStream out = res.getOutputStream(); //创建页面返回方式为输出流,会自动弹出下载框 

//方法1-1:IO字节流下载,用于小文件 
InputStream is = new FileInputStream(filePath); //创建文件输入流  
byte[] Buffer = new byte[2048]; //设置每次读取数据大小,即缓存大小  
int size = 0; //用于计算缓存数据是否已经读取完毕,如果数据已经读取完了,则会返回-1  
while((size=is.read(Buffer)) != -1){ //循环读取数据,如果数据读取完毕则返回-1  
	out.write(Buffer, 0, size); //将每次读取到的数据写入客户端  } 
is.close();

//方法1-2:IO字节流下载,用于大文件 
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath)); //创建文件缓冲输入流 
byte[] buff = new byte[bis.available()];//从输入流中读取不受阻塞
bis.read(buff);//读取数据文件
bis.close();
out.write(buff);//输出数据文件
out.flush();//释放缓存
out.close();//关闭输出流

创建临时压缩文件代码:

/**
 * @param filePaths 需要压缩的文件路径集合
 * @param zos 临时压缩文件输出流
 * @return
 * @throws IOException
 */
private String zipFile(List<String> filePaths,ZipOutputStream zos) throws IOException { 
	//循环读取文件路径集合,获取每一个文件的路径  
	for(String filePath : filePaths){ 
		File inputFile = new File(filePath); //根据文件路径创建文件
		if(inputFile.exists()) { //判断文件是否存在  
			if (inputFile.isFile()) { //判断是否属于文件,还是文件夹 
				//创建输入流读取文件  
				BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inputFile)); 
				//将文件写入zip内,即将文件进行打包  
				zos.putNextEntry(new ZipEntry(inputFile.getName())); 
				//写入文件的方法,同上                  
				int size = 0; 
				byte[] buffer = new byte[1024]; //设置读取数据缓存大小			 
				while ((size = bis.read(buffer)) > 0) { 
					zos.write(buffer, 0, size); 
				} 
				//关闭输入输出流  
				zos.closeEntry(); 
				bis.close(); 
			} else { 
				//如果是文件夹,则使用穷举的方法获取文件,写入zip  
				try { 
					File[] files = inputFile.listFiles(); 
					List<String> filePathsTem = new ArrayList<String>(); 
					for (File fileTem:files) { 
						filePathsTem.add(fileTem.toString()); 
					} 
					return zipFile(filePathsTem,zos); 
				} catch (Exception e) { 
					e.printStackTrace(); 
				} 
			} 
		} 
	} 
	return null; 
}