1 文件上传
1.1 实现文件上传条件
1)表单的提交方式必须是POST方式。(才有content-type属性)
2)有文件上传表单,表单中有的选择文件的标签
3)把表单设置为enctype=”multipart/form-data”,提交的数据不再是key-value对,而是字节数据
1 2 3 4
   | <form action="${pageContext.request.contextPath }/UploadDemo1" method="post" enctype="multipart/form-data">     	请选择文件: <input type="file" name="img"/><br/>     	<input type="submit" value="上传" /> </form>
  | 
 
1.2 手动解析上传文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
   | 
 
 
 
  public class UploadDemo1 extends HttpServlet {
  	public void doGet(HttpServletRequest request, HttpServletResponse response) 			throws ServletException, IOException { 		 		InputStream in = request.getInputStream(); 		BufferedReader br = new BufferedReader(new InputStreamReader(in)); 		 		 		String startTag = br.readLine(); 		 		 		String line = br.readLine(); 		String fileName = line.substring(line.lastIndexOf("filename=\"")+10, line.lastIndexOf("\"") ); 		System.out.println("文件名:"+fileName); 		 		 		br.readLine(); 		br.readLine(); 		 		 		String str = null; 		BufferedWriter bw = new BufferedWriter(new FileWriter("E:/files/"+fileName)); 		while((str=br.readLine())!=null){ 			 			if((startTag+"--").equals(str)){ 				break; 			} 			 			 			bw.write(str); 			bw.newLine(); 			bw.flush(); 		} 		 		bw.close(); 		br.close(); 	}
  	public void doPost(HttpServletRequest request, HttpServletResponse response) 			throws ServletException, IOException { 		doGet(request, response); 	}
  }
 
  | 
 
2 工具实现文件上传
2.1 commons-fileupload组件
是Apache组织旗下的开源的文件上传的组件。使用非常简单易用。
2.2 核心的API
DiskFileItemFactory类: 用于创建上传对象,设置文件缓存区大小,设置文件缓存目录。
ServletFileUpload类: 用于在Servlet程序中实现文件上传
List list = parseRequest(request): 用于解析请求数据,提取和封装文件信息。
FileItem类: 封装一个文件的所有相关的信息javabean。包含文件名称,文件大小,文件类型, 文件数据内容。
2.3 开发步骤
1)导入commoms-fileuload的jar包
commons-fileupload-1.2.2.jar 核心包
commons-io-2.1.jar 辅助包
2)编写程序
3 实现单文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
   |  		
 
 
  		DiskFileItemFactory factory = new DiskFileItemFactory(10*1024,new File("e:/temp/")); 		 		 		ServletFileUpload upload = new ServletFileUpload(factory); 		 		
 
  		upload.setHeaderEncoding("utf-8"); 		 		 		try { 			List<FileItem> list = upload.parseRequest(request); 			 			 			FileItem file = list.get(0); 			 			 			String fileName = file.getName(); 			 			long fileSize = file.getSize(); 			 			String contentType = file.getContentType(); 			 			InputStream in = file.getInputStream(); 			 			
 
  			FileUtils.copyInputStreamToFile(in, new File("e:/files/"+fileName)); 			 			
 
  			file.delete(); 			 			 			System.out.println("文件名:"+fileName); 			System.out.println("文件大小:"+fileSize); 			System.out.println("文件类型:"+contentType); 			System.out.println("文件数据内容:"+in); 			 		} catch (FileUploadException e) { 			e.printStackTrace(); 		}
 
  | 
 
4 实现多文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   |  		DiskFileItemFactory factory = new DiskFileItemFactory(10*1024, new File("e:/temp/")); 		 		ServletFileUpload upload = new ServletFileUpload(factory); 		 		upload.setHeaderEncoding("utf-8"); 		 		try { 			List<FileItem> list = upload.parseRequest(request); 			if(list!=null){ 				List<UploadFile> ufList = new ArrayList<UploadFile>(); 				 				for(FileItem file: list){ 					 					String fileName = file.getName(); 					long fileSize = file.getSize(); 					String contentType = file.getContentType(); 					 					UploadFile uf = new UploadFile(); 					uf.setFileName(fileName); 					uf.setFileSize(fileSize); 					uf.setFileType(contentType); 					 					ufList.add(uf); 					 					 					FileUtils.copyInputStreamToFile(file.getInputStream(), new File("e:/files/"+fileName)); 					 					file.delete(); 				} 				request.setAttribute("ufList", ufList); 				request.getRequestDispatcher("/success.jsp").forward(request, response); 			} 		} catch (FileUploadException e) { 			e.printStackTrace(); 		}
 
  | 
 
5 动态选择多文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
   | <html>   <head>      <title>使用组件实现动态多文件上传</title>     </head>      <body>     <form action="${pageContext.request.contextPath }/UploadDemo3" method="post" enctype="multipart/form-data" name="uploadForm">     	<table border="1" width="400px">     		<tbody>     		<tr id="1">     			<td>     			请选择文件:     			</td>     			<td>     				<input type="file" name="file"/><input type="button" value="删除" οnclick="delItem(1)"/>     			</td>     		</tr>     		</tbody>     		<tr>     			<td colspan="2"><input type="button" value="添加" οnclick="addIten()"/></td>     		</tr>     		<tr>     			<td colspan="2"><input type="button" value="上传" οnclick="checkSunbit()"/></td>     		</tr>     	</table>     </form>          <script type="text/javascript">     	var id = 2;     	     	function addIten(){     		var trNode = document.createElement("tr");     		trNode.setAttribute("id", id);     		     		var tdNode1 = document.createElement("td");     		tdNode1.innerHTML = "请选择文件:";     		     		var tdNode2 = document.createElement("td");     		var input1 = document.createElement("input");     		input1.setAttribute("type", "file");     		input1.setAttribute("name", "file");     		var input2 = document.createElement("input");     		input2.setAttribute("type", "button");     		input2.setAttribute("value", "删除");     		input2.setAttribute("onclick", "delItem("+id+")");     		tdNode2.appendChild(input1);     		tdNode2.appendChild(input2);     		     		trNode.appendChild(tdNode1);     		trNode.appendChild(tdNode2);     		     		var tbodyNode = document.getElementsByTagName("tbody")[0];     		tbodyNode.appendChild(trNode);     		     		id++;     		     	}     	     	     	function delItem(id){     		if(id>1){ 	    		var trNode = document.getElementById(id); 	    		var tbodyNode = document.getElementsByTagName("tbody")[0]; 	    		tbodyNode.removeChild(trNode); 	    		 	    		id--;     		}     	}     	     	     	function checkSunbit(){     		     		var fileList = document.getElementsByName("file");     		for(var i=0;i<fileList.length;i++){     			     			if(fileList[i].value==null || fileList[i].value==""){     				alert("请选择第"+(i+1)+"个文件");     				return;     			}     		}     		     		     		var form = document.forms['uploadForm'];     		form.submit();     	}     </script>   </body> </html>
   | 
 
6 文件上传的细节
6.1 限制文件类型
1 2 3 4 5 6 7
   |  					String contentType = file.getContentType(); 					System.out.println(contentType); 					 					if(!contentType.toLowerCase().matches("image/[a-z]*")){ 						throw new FileTypeErrorException("文件类型不符合条件!"); 					}
 
  | 
 
6.2 限制上传文件大小
ServletFileUpload类:
setFileSizeMax:设置单个文件的最大容量。
setSizeMax : 设置所有文件的最大容量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
   |  		try { 			List<FileItem> list = upload.parseRequest(request); 			if(list!=null){ 				for(FileItem file : list){ 					
 
  					 					String contentType = file.getContentType(); 					System.out.println(contentType); 					 					if(!contentType.toLowerCase().matches("image/[a-z]*")){ 						throw new FileTypeErrorException("文件类型不符合条件!"); 					} 					 					 					FileUtils.copyInputStreamToFile(file.getInputStream(), new File("e:/files/"+file.getName())); 					 					file.delete(); 				} 			} 		} catch (FileTypeErrorException e) { 			 			 			request.setAttribute("message", e.getMessage()); 			request.getRequestDispatcher("/05.upload.jsp").forward(request, response); 			return; 		} catch (FileSizeLimitExceededException e) { 			 			 			request.setAttribute("message", "单个文件不能超过1M"); 			request.getRequestDispatcher("/05.upload.jsp").forward(request, response); 			return; 		}  catch (SizeLimitExceededException e) { 			 			 			request.setAttribute("message", "所有文件不能超过5M"); 			request.getRequestDispatcher("/05.upload.jsp").forward(request, response); 			return; 		} catch (FileUploadException e) { 			e.printStackTrace(); 		}
 
  | 
 
6.3 查看文件上传的进度
ServletFileUpload类:
setProgressListener(进度监听器):设置文件上传的监听器
6.4 处理文件名重复问题
1 2 3 4 5 6 7 8 9 10
   | 
 
 
 
  					String fileName = file.getName(); 					 					String supfix = fileName.substring(fileName.lastIndexOf("."));  					 					fileName = UUID.randomUUID().toString()+supfix;
 
  | 
 
6.5 把同一个目录的文件打散到不同的目录下
假如所有文件都放在同一个目录下,不方便管理。
6.6 得到普通文本控件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   |  					if(file.isFormField()){ 						 						 						 						 						
  						 						 						 						String fieldName = file.getFieldName(); 						if("info1".equals(fieldName)){ 							String info1 = file.getString("utf-8"); 							System.out.println("描述1:"+info1); 						} 						if("info2".equals(fieldName)){ 							String info2 = file.getString("utf-8"); 							System.out.println("描述2:"+info2); 						}
 
  | 
 
7 文件下载
7.1 普通文件下载
使用超链接。缺点:1)暴露文件的路径2)扩展型和安全性不好
7.2 使用servlet程序下载(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   |  		String path = this.getServletContext().getRealPath("/upload/9/1/图片1.png"); 		 		File file = new File(path); 		 		FileInputStream in = new FileInputStream(file); 		 		
 
  		String fileName = file.getName(); 		 		fileName = URLEncoder.encode(fileName, "utf-8"); 		 		 		String userAgent = request.getHeader("user-agent"); 		String filefix = null; 		if(userAgent.contains("Trident")){ 			 			filefix = "filename="+fileName; 		}else if(userAgent.contains("Firefox")){ 			 			filefix = "filename*="+fileName; 		}else{ 			filefix = "filename="+fileName; 		} 		 		 		response.setHeader("Content-Disposition", "attachment;"+filefix); 		 		 		byte[] buf = new byte[1024]; 		int len = 0; 		while( (len=in.read(buf))!=-1 ){ 			response.getOutputStream().write(buf, 0, len); 		} 		 		in.close();
 
  | 
 
 本作品采用知识共享署名 4.0 中国大陆许可协议进行许可,欢迎转载,但转载请注明来自御前提笔小书童,并保持转载后文章内容的完整。本人保留所有版权相关权利。
本文链接:https://royalscholar.cn/2017/03/15/Java文件上传与下载/