java web开发,常用到的文件上传功能,常用的commons-fileupload和commons-io两个jar包。关于如何使用这两个jar来完成文件上传的功能,这里不做详解。使用commons-fileupload来上传文件,有两种方式可以是实现。
1. 传统API
1 <%@page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java"%> 2 <%@page import="java.io.File"%> 3 <%@page import="java.util.List"%> 4 <%@page import="org.apache.commons.fileupload.*"%> 5 <%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%> 6 <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%> 7 8 <% 9 request.setCharacterEncoding("UTF-8"); 10 // file less than 10kb will be store in memory, otherwise in file system. 11 final int threshold = 10240; 12 final File tmpDir = new File(getServletContext().getRealPath("/") + "fileupload" + File.separator + "tmp"); 13 final int maxRequestSize = 1024 * 1024 * 4; // 4MB 14 15 // Check that we have a file upload request 16 if(ServletFileUpload.isMultipartContent(request)) 17 { 18 // Create a factory for disk-based file items. 19 FileItemFactory factory = new DiskFileItemFactory(threshold, tmpDir); 20 21 // Create a new file upload handler 22 ServletFileUpload upload = new ServletFileUpload(factory); 23 24 // Set overall request size constraint. 25 upload.setSizeMax(maxRequestSize); 26 27 List<FileItem> items = upload.parseRequest(request); // FileUploadException 28 for(FileItem item : items) 29 { 30 if(item.isFormField()) //regular form field 31 { 32 String name = item.getFieldName(); 33 String value = item.getString(); 34 %> 35 <h1><%=name%> --> <%=value%></h1> 36 <% 37 } 38 else 39 { //file upload 40 String fieldName = item.getFieldName(); 41 String fileName = item.getName(); 42 File uploadedFile = new File(getServletContext().getRealPath("/") + 43 "fileupload" + File.separator + fieldName + "_" + fileName); 44 item.write(uploadedFile); 45 %> 46 <h1>upload file <%=uploadedFile.getName()%> done!</h1> 47 <% 48 } 49 } 50 } 51 %>
2. Stream API
1 <%@page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java"%> 2 <%@page import="java.io.*"%> 3 <%@page import="java.util.List"%> 4 <%@page import="org.apache.commons.fileupload.*"%> 5 <%@page import="org.apache.commons.fileupload.util.Streams"%> 6 <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%> 7 8 <% 9 request.setCharacterEncoding("UTF-8"); 10 11 // Check that we have a file upload request 12 if(ServletFileUpload.isMultipartContent(request)) 13 { 14 // Create a new file upload handler 15 ServletFileUpload upload = new ServletFileUpload(); 16 17 // Parse the request 18 FileItemIterator iter = upload.getItemIterator(request); 19 20 while(iter.hasNext()) 21 { 22 FileItemStream item = iter.next(); 23 String fieldName = item.getFieldName(); 24 InputStream is = item.openStream(); 25 26 if(item.isFormField()) //regular form field 27 { 28 %> 29 <!-- read a FileItemStream's content into a string. --> 30 <h1><%=fieldName%> --> <%=Streams.asString(is)%></h1> 31 <% 32 } 33 else 34 { //file upload 35 String fileName = item.getName(); 36 File uploadedFile = new File(getServletContext().getRealPath("/") + 37 "fileupload" + File.separator + fieldName + "_" + fileName); 38 OutputStream os = new FileOutputStream(uploadedFile); 39 // write file to disk and close outputstream. 40 Streams.copy(is, os, true); 41 %> 42 <h1>upload file <%=uploadedFile.getName()%> done!</h1> 43 <% 44 } 45 } 46 } 47 %>
Streaming API上传速度相对较快。因为它是利用内存保存上传的文件,节省了传统API将文件写入临时文件带来的开销。自然,更倾向于选用Stream API。
前端实现文件上传的“手段”,目前接触过的有UEditor的上传组件、jQuery的ajaxfileupload以及AngularJs的集成上传组件。发送的也都是正常的上传表单数据,而当使用Stream API,获取文件名时,“String fileName = item.getName()”,当文件名为中文名时,会出现乱码现象。
网上搜寻的关于设置request编码的法子都不管用,尝试了多次后,找到了解决办法,重点在于上面代码中的ServletFileUpload upload,添加upload.setHeaderEncoding("UTF-8");即可解决中文文件名的乱码问题了。