MultipartFile的源碼

1 package org.springframework.web.multipart; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import org.springframework.core.io.InputStreamSource; 7 8 public interface MultipartFile extends InputStreamSource { 9 String getName(); 10 11 String getOriginalFilename(); 12 13 String getContentType(); 14 15 boolean isEmpty(); 16 17 long getSize(); 18 19 byte[] getBytes() throws IOException; 20 21 InputStream getInputStream() throws IOException; 22 23 void transferTo(File var1) throws IOException, IllegalStateException; 24 }
CommonsMultipartFile 部分源碼

1 package org.springframework.web.multipart.commons; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.Serializable; 7 import org.apache.commons.fileupload.FileItem; 8 import org.apache.commons.fileupload.FileUploadException; 9 import org.apache.commons.fileupload.disk.DiskFileItem; 10 import org.apache.commons.logging.Log; 11 import org.apache.commons.logging.LogFactory; 12 import org.springframework.util.StreamUtils; 13 import org.springframework.web.multipart.MultipartFile; 14 15 public class CommonsMultipartFile implements MultipartFile, Serializable { 16 protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class); 17 private final FileItem fileItem; 18 private final long size; 19 private boolean preserveFilename = false; 20 21 public CommonsMultipartFile(FileItem fileItem) { 22 this.fileItem = fileItem; 23 this.size = this.fileItem.getSize(); 24 } 25 26 /** 27 * 獲取上傳文件的原文件名 28 */ 29 public String getOriginalFilename() { 30 String filename = this.fileItem.getName(); 31 if (filename == null) { 32 return ""; 33 } else if (this.preserveFilename) { 34 return filename; 35 } else { 36 int unixSep = filename.lastIndexOf(47); 37 int winSep = filename.lastIndexOf(92); 38 int pos = winSep > unixSep ? winSep : unixSep; 39 return pos != -1 ? filename.substring(pos + 1) : filename; 40 } 41 } 42 43 /** 44 * 獲取上傳文件的文件輸入流 45 */ 46 public InputStream getInputStream() throws IOException { 47 if (!this.isAvailable()) { 48 throw new IllegalStateException("File has been moved - cannot be read again"); 49 } else { 50 InputStream inputStream = this.fileItem.getInputStream(); 51 return inputStream != null ? inputStream : StreamUtils.emptyInput(); 52 } 53 } 54 55 /** 56 * 將CommonsMultipartFile 轉化成 File , 即將上傳的文件寫入指定文件 57 */ 58 public void transferTo(File dest) throws IOException, IllegalStateException { 59 if (!this.isAvailable()) { 60 throw new IllegalStateException("File has already been moved - cannot be transferred again"); 61 } else if (dest.exists() && !dest.delete()) { 62 throw new IOException("Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted"); 63 } else { 64 try { 65 this.fileItem.write(dest); 66 if (logger.isDebugEnabled()) { 67 String action = "transferred"; 68 if (!this.fileItem.isInMemory()) { 69 action = this.isAvailable() ? "copied" : "moved"; 70 } 71 72 logger.debug("Multipart file '" + this.getName() + "' with original filename [" + this.getOriginalFilename() + "], stored " + this.getStorageDescription() + ": " + action + " to [" + dest.getAbsolutePath() + "]"); 73 } 74 75 } catch (FileUploadException var3) { 76 throw new IllegalStateException(var3.getMessage(), var3); 77 } catch (IllegalStateException var4) { 78 throw var4; 79 } catch (IOException var5) { 80 throw var5; 81 } catch (Exception var6) { 82 throw new IOException("File transfer failed", var6); 83 } 84 } 85 } 86 87 }
異同:
1、MultipartFile 和 CommonsMultipartFile都是用來接收上傳的文件流的 !
2、MultipartFile是一個接口,CommonsMultipartFile是MultipartFile接口的實現類 !
3、使用MultipartFile作為形參接收上傳文件時,直接用即可。CommonsMultipartFile作為形參接收上傳文件時,必需添加@RequestParam注解(否則會報錯:exception is java.lang.NoSuchMethodException: org.springframework.web.multipart.commons.CommonsMultipartFile)
MultipartFile

1 @RequestMapping(value = "/uploadFile") 2 @ResponseBody //@ResponseBody注解會將這個方法的返回值轉換為JSON形式的數據,返回到response中,可以抽象理解成response.getWriter.write(JSON.toJSONString(map)); 3 public Map<String,Object> uploadFile(MultipartFile uploadFile, HttpServletRequest request) throws IOException { 4 Map<String,Object> map = new HashMap<String, Object>(); 5 //判斷文件是否成功上傳 6 if(uploadFile!=null){ 7 // 獲取上傳文件的原文件名 8 String fileName = uploadFile.getOriginalFilename(); 9 // 獲取上傳文件的后綴名 10 String suffix=fileName.substring(fileName.lastIndexOf(".")); 11 // 給文件定義一個新的名稱,杜絕文件重名覆蓋現象 (UUID是全球唯一id) 12 String newFileName= UUID.randomUUID().toString()+suffix; 13 // 指定文件存儲目錄 14 String basePath = "C:/Users/CD4356/Pictures/image/"; 15 // 創建File對象,注意這里不是創建一個目錄或一個文件,你可以理解為是 獲取指定目錄中文件的管理權限(增改刪除判斷等 . . .) 16 File tempFile=new File(basePath); 17 // 判斷File對象對應的目錄是否存在 18 if(!tempFile.exists()){ 19 // 創建以此抽象路徑名命名的目錄,注意mkdir()只能創建一級目錄,所以它的父級目錄必須存在 20 tempFile.mkdir(); 21 } 22 //拼接文件存儲的絕對路徑 23 String path = basePath + newFileName; 24 // 在指定路徑中創建一個文件(該文件是空的) 25 File file=new File(path); 26 try{ 27 // 將上傳的文件寫入指定文件 28 uploadFile.transferTo(file); 29 map.put("success",true); 30 }catch (Exception e){ 31 map.put("success",false); 32 map.put("errorMsg",e.getMessage()); 33 return map; 34 } 35 } 36 return map; 37 }
CommonsMultipartFile

1 @RequestMapping(value = "/uploadFile") 2 @ResponseBody //@ResponseBody注解會將這個方法的返回值轉換為JSON形式的數據,返回到response中,可以抽象理解成response.getWriter.write(JSON.toJSONString(map)); 3 public Map<String,Object> uploadFile(@RequestParam CommonsMultipartFile uploadFile, HttpServletRequest request) throws IOException { 4 Map<String,Object> map = new HashMap<String, Object>(); 5 //判斷文件是否成功上傳 6 if(uploadFile!=null){ 7 // 獲取上傳文件的原文件名 8 String fileName = uploadFile.getOriginalFilename(); 9 // 獲取上傳文件的后綴名 10 String suffix=fileName.substring(fileName.lastIndexOf(".")); 11 // 給文件定義一個新的名稱,杜絕文件重名覆蓋現象 (UUID是全球唯一id) 12 String newFileName= UUID.randomUUID().toString()+suffix; 13 // 指定文件存儲目錄 14 String basePath = "C:/Users/CD4356/Pictures/image/"; 15 // 創建File對象,注意這里不是創建一個目錄或一個文件,你可以理解為是 獲取指定目錄中文件的管理權限(增改刪除判斷等 . . .) 16 File tempFile=new File(basePath); 17 // 判斷File對象對應的目錄是否存在 18 if(!tempFile.exists()){ 19 // 創建以此抽象路徑名命名的目錄,注意mkdir()只能創建一級目錄,所以它的父級目錄必須存在 20 tempFile.mkdir(); 21 } 22 //拼接文件存儲的絕對路徑 23 String path = basePath + newFileName; 24 // 在指定路徑中創建一個文件(該文件是空的) 25 File file=new File(path); 26 try{ 27 // 將上傳的文件寫入指定文件 28 uploadFile.transferTo(file); 29 map.put("success",true); 30 }catch (Exception e){ 31 map.put("success",false); 32 map.put("errorMsg",e.getMessage()); 33 return map; 34 } 35 } 36 return map; 37 }
當然,我們也可以不在方法中定義MultipartFile 或 CommonsMultipartFile來接收文件信息,而是從request請求中獲取。

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>CommonsMultipartFile</title> 6 </head> 7 <body> 8 <div> 9 <form action="uploadFile" method="post" enctype="multipart/form-data"> 10 <input type="file" name="uploadFile" accept="image/*"><br><br> 11 <input type="submit" value="上傳"> 12 </form> 13 </div> 14 </body> 15 </html>

1 @Controller 2 public class UploadController { 3 4 @RequestMapping("to_upload") 5 public String toUpload(){ 6 return "upload_file"; 7 } 8 9 @RequestMapping(value = "/uploadFile") 10 @ResponseBody //@ResponseBody注解會將這個方法的返回值轉換為JSON形式的數據,返回到response中,可以抽象理解成response.getWriter.write(JSON.toJSONString(map)); 11 public Map<String,Object> uploadFile(HttpServletRequest request) throws IOException { 12 Map<String,Object> map = new HashMap<String, Object>(); 13 14 //創建一個CommonsMultipartFile對象,獲取上傳到request中的文件 15 CommonsMultipartFile uploadFile = null; 16 //創建文件解析器(目的是調用該對象的isMultipart方法來檢測request請求中是否有上傳文件) 17 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); 18 //判斷request中是否有上傳文件流 19 if(multipartResolver.isMultipart(request)){ 20 //將request轉為MultipartHttpServletRequest 21 MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request; 22 //從request中獲取key名為uploadFile的文件,並保存的CommonsMultipartFile對象中 23 uploadFile = (CommonsMultipartFile) multipartHttpServletRequest.getFile("uploadFile"); 24 } 25 26 // 獲取上傳文件的原文件名 27 String fileName = uploadFile.getOriginalFilename(); 28 // 獲取上傳文件的后綴名 29 String suffix=fileName.substring(fileName.lastIndexOf(".")); 30 // 給文件定義一個新的名稱,杜絕文件重名覆蓋現象 (UUID是全球唯一id) 31 String newFileName= UUID.randomUUID().toString()+suffix; 32 // 指定文件存儲目錄 33 String basePath = "C:/Users/CD4356/Pictures/image/"; 34 // 創建File對象,注意這里不是創建一個目錄或一個文件,你可以理解為是 獲取指定目錄中文件的管理權限(增改刪除判斷等 . . .) 35 File tempFile=new File(basePath); 36 // 判斷File對象對應的目錄是否存在 37 if(!tempFile.exists()){ 38 // 創建以此抽象路徑名命名的目錄,注意mkdir()只能創建一級目錄,所以它的父級目錄必須存在 39 tempFile.mkdir(); 40 } 41 //拼接文件存儲的絕對路徑 42 String path = basePath + newFileName; 43 // 在指定路徑中創建一個文件(該文件是空的) 44 File file=new File(path); 45 try{ 46 // 將上傳的文件寫入指定文件 47 uploadFile.transferTo(file); 48 map.put("success",true); 49 }catch (Exception e){ 50 map.put("success",false); 51 map.put("errorMsg",e.getMessage()); 52 return map; 53 } 54 55 return map; 56 } 57 58 }