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 }