天天看點

MultipartFile和CommonsMultipartFile的差別!

MultipartFile 源碼

package org.springframework.web.multipart;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.InputStreamSource;

public interface MultipartFile extends InputStreamSource {
    String getName();

    String getOriginalFilename();

    String getContentType();

    boolean isEmpty();

    long getSize();

    byte[] getBytes() throws IOException;

    InputStream getInputStream() throws IOException;

    void transferTo(File var1) throws IOException, IllegalStateException;
}
           

CommonsMultipartFile 部分源碼

package org.springframework.web.multipart.commons;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StreamUtils;
import org.springframework.web.multipart.MultipartFile;

public class CommonsMultipartFile implements MultipartFile, Serializable {
    protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class);
    private final FileItem fileItem;
    private final long size;
    private boolean preserveFilename = false;

    public CommonsMultipartFile(FileItem fileItem) {
        this.fileItem = fileItem;
        this.size = this.fileItem.getSize();
    }

	/**
	 *	擷取上傳檔案的原檔案名
	 */
    public String getOriginalFilename() {
        String filename = this.fileItem.getName();
        if (filename == null) {
            return "";
        } else if (this.preserveFilename) {
            return filename;
        } else {
            int unixSep = filename.lastIndexOf(47);
            int winSep = filename.lastIndexOf(92);
            int pos = winSep > unixSep ? winSep : unixSep;
            return pos != -1 ? filename.substring(pos + 1) : filename;
        }
    }

	/**
	 *	擷取上傳檔案的檔案輸入流
	 */
    public InputStream getInputStream() throws IOException {
        if (!this.isAvailable()) {
            throw new IllegalStateException("File has been moved - cannot be read again");
        } else {
            InputStream inputStream = this.fileItem.getInputStream();
            return inputStream != null ? inputStream : StreamUtils.emptyInput();
        }
    }

	/**
	 *	将CommonsMultipartFile 轉化成 File , 即将上傳的檔案寫入指定檔案
	 */
    public void transferTo(File dest) throws IOException, IllegalStateException {
        if (!this.isAvailable()) {
            throw new IllegalStateException("File has already been moved - cannot be transferred again");
        } else if (dest.exists() && !dest.delete()) {
            throw new IOException("Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
        } else {
            try {
                this.fileItem.write(dest);
                if (logger.isDebugEnabled()) {
                    String action = "transferred";
                    if (!this.fileItem.isInMemory()) {
                        action = this.isAvailable() ? "copied" : "moved";
                    }

                    logger.debug("Multipart file '" + this.getName() + "' with original filename [" + this.getOriginalFilename() + "], stored " + this.getStorageDescription() + ": " + action + " to [" + dest.getAbsolutePath() + "]");
                }

            } catch (FileUploadException var3) {
                throw new IllegalStateException(var3.getMessage(), var3);
            } catch (IllegalStateException var4) {
                throw var4;
            } catch (IOException var5) {
                throw var5;
            } catch (Exception var6) {
                throw new IOException("File transfer failed", var6);
            }
        }
    }

}
           

異同:

1、MultipartFile 和 CommonsMultipartFile都是用來接收上傳的檔案流的 !

2、MultipartFile是一個接口,CommonsMultipartFile是MultipartFile接口的實作類 !

3、使用MultipartFile作為形參接收上傳檔案時,直接用即可。CommonsMultipartFile作為形參接收上傳檔案時,必需添加@RequestParam注解(否則會報錯:exception is java.lang.NoSuchMethodException: org.springframework.web.multipart.commons.CommonsMultipartFile)

MultipartFile

@RequestMapping(value = "/uploadFile")
@ResponseBody //@ResponseBody注解會将這個方法的傳回值轉換為JSON形式的資料,傳回到response中,可以抽象了解成response.getWriter.write(JSON.toJSONString(map));
public Map<String,Object> uploadFile(MultipartFile uploadFile, HttpServletRequest request) throws IOException {
    Map<String,Object> map = new HashMap<String, Object>();
    //判斷檔案是否成功上傳
    if(uploadFile!=null){
        // 擷取上傳檔案的原檔案名
        String fileName = uploadFile.getOriginalFilename();
        // 擷取上傳檔案的字尾名
        String suffix=fileName.substring(fileName.lastIndexOf("."));
        // 給檔案定義一個新的名稱,杜絕檔案重名覆寫現象 (UUID是全球唯一id)
        String newFileName= UUID.randomUUID().toString()+suffix;
        // 指定檔案存儲目錄
        String basePath = "C:/Users/CD4356/Pictures/image/";
        // 建立File對象,注意這裡不是建立一個目錄或一個檔案,你可以了解為是 擷取指定目錄中檔案的管理權限(增改删除判斷等 . . .)
        File tempFile=new File(basePath);
        // 判斷File對象對應的目錄是否存在
        if(!tempFile.exists()){
            // 建立以此抽象路徑名命名的目錄,注意mkdir()隻能建立一級目錄,是以它的父級目錄必須存在
            tempFile.mkdir();
        }
        //拼接檔案存儲的絕對路徑
        String path = basePath + newFileName;
        // 在指定路徑中建立一個檔案(該檔案是空的)
        File file=new File(path);
        try{
            // 将上傳的檔案寫入指定檔案
            uploadFile.transferTo(file);
            map.put("success",true);
        }catch (Exception e){
            map.put("success",false);
            map.put("errorMsg",e.getMessage());
            return map;
        }
    }
    return map;
}
           

CommonsMultipartFile

@RequestMapping(value = "/uploadFile")
@ResponseBody //@ResponseBody注解會将這個方法的傳回值轉換為JSON形式的資料,傳回到response中,可以抽象了解成response.getWriter.write(JSON.toJSONString(map));
public Map<String,Object> uploadFile(@RequestParam CommonsMultipartFile uploadFile, HttpServletRequest request) throws IOException {
    Map<String,Object> map = new HashMap<String, Object>();
    //判斷檔案是否成功上傳
    if(uploadFile!=null){
        // 擷取上傳檔案的原檔案名
        String fileName = uploadFile.getOriginalFilename();
        // 擷取上傳檔案的字尾名
        String suffix=fileName.substring(fileName.lastIndexOf("."));
        // 給檔案定義一個新的名稱,杜絕檔案重名覆寫現象 (UUID是全球唯一id)
        String newFileName= UUID.randomUUID().toString()+suffix;
        // 指定檔案存儲目錄
        String basePath = "C:/Users/CD4356/Pictures/image/";
        // 建立File對象,注意這裡不是建立一個目錄或一個檔案,你可以了解為是 擷取指定目錄中檔案的管理權限(增改删除判斷等 . . .)
        File tempFile=new File(basePath);
        // 判斷File對象對應的目錄是否存在
        if(!tempFile.exists()){
            // 建立以此抽象路徑名命名的目錄,注意mkdir()隻能建立一級目錄,是以它的父級目錄必須存在
            tempFile.mkdir();
        }
        //拼接檔案存儲的絕對路徑
        String path = basePath + newFileName;
        // 在指定路徑中建立一個檔案(該檔案是空的)
        File file=new File(path);
        try{
            // 将上傳的檔案寫入指定檔案
            uploadFile.transferTo(file);
            map.put("success",true);
        }catch (Exception e){
            map.put("success",false);
            map.put("errorMsg",e.getMessage());
            return map;
        }
    }
    return map;
}
           

當然,我們也可以不在方法中定義MultipartFile 或 CommonsMultipartFile來接收檔案資訊,而是從request請求中擷取。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CommonsMultipartFile</title>
</head>
<body>
<div>
    <form action="uploadFile" method="post" enctype="multipart/form-data">
        <input type="file" name="uploadFile" accept="image/*"><br><br>
        <input type="submit" value="上傳">
    </form>
</div>
</body>
</html>
           
@Controller
public class UploadController {

    @RequestMapping("to_upload")
    public String toUpload(){
        return "upload_file";
    }

    @RequestMapping(value = "/uploadFile")
    @ResponseBody //@ResponseBody注解會将這個方法的傳回值轉換為JSON形式的資料,傳回到response中,可以抽象了解成response.getWriter.write(JSON.toJSONString(map));
    public Map<String,Object> uploadFile(HttpServletRequest request) throws IOException {
        Map<String,Object> map = new HashMap<String, Object>();

		//建立一個CommonsMultipartFile對象,擷取上傳到request中的檔案
        CommonsMultipartFile uploadFile = null;
        //建立檔案解析器(目的是調用該對象的isMultipart方法來檢測request請求中是否有上傳檔案)
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
         //判斷request中是否有上傳檔案流
        if(multipartResolver.isMultipart(request)){
        	//将request轉為MultipartHttpServletRequest
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            //從request中擷取key名為uploadFile的檔案,并儲存的CommonsMultipartFile對象中
            uploadFile = (CommonsMultipartFile) multipartHttpServletRequest.getFile("uploadFile");
        }
       
       // 擷取上傳檔案的原檔案名
        String fileName = uploadFile.getOriginalFilename();
        // 擷取上傳檔案的字尾名
        String suffix=fileName.substring(fileName.lastIndexOf("."));
        // 給檔案定義一個新的名稱,杜絕檔案重名覆寫現象 (UUID是全球唯一id)
        String newFileName= UUID.randomUUID().toString()+suffix;
        // 指定檔案存儲目錄
        String basePath = "C:/Users/CD4356/Pictures/image/";
        // 建立File對象,注意這裡不是建立一個目錄或一個檔案,你可以了解為是 擷取指定目錄中檔案的管理權限(增改删除判斷等 . . .)
        File tempFile=new File(basePath);
        // 判斷File對象對應的目錄是否存在
        if(!tempFile.exists()){
            // 建立以此抽象路徑名命名的目錄,注意mkdir()隻能建立一級目錄,是以它的父級目錄必須存在
            tempFile.mkdir();
        }
        //拼接檔案存儲的絕對路徑
        String path = basePath + newFileName;
        // 在指定路徑中建立一個檔案(該檔案是空的)
        File file=new File(path);
        try{
            // 将上傳的檔案寫入指定檔案
            uploadFile.transferTo(file);
            map.put("success",true);
        }catch (Exception e){
            map.put("success",false);
            map.put("errorMsg",e.getMessage());
            return map;
        }
        
        return map;
    }

}
           

繼續閱讀