1. 程式人生 > >SpringBoot系列(九)單,多檔案上傳的正確姿勢

SpringBoot系列(九)單,多檔案上傳的正確姿勢

SpringBoot系列(九)分分鐘解決檔案上傳

往期推薦
SpringBoot系列(一)idea新建Springboot專案

SpringBoot系列(二)入門知識

springBoot系列(三)配置檔案詳解

SpringBoot系列(四)web靜態資源配置詳解

SpringBoot系列(五)Mybatis整合完整詳細版

SpringBoot系列(六)整合thymeleaf詳解版

Springboot系列(七) 整合介面文件swagger,使用,測試

SpringBoot系列(八)分分鐘學會Springboot多種解決跨域方式

1.專案搭建與配置

 我們直接建立一個包含web依賴的專案就好了。
然後需要在配置檔案配置檔案上傳的一些設定。這裡使用yml檔案作為配置檔案,如果不懂語法的,請移步前面的系列三,裡面有詳細解釋。

server:
  port: 8095

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 30MB
  • max-file-size 設定能接受的檔案最大的大小,記得是MB,或KB
  • max-request-size 設定一次上傳的所有檔案的大小。

 預設大小為1MB

 除了可以用配置檔案配置還可利用java配置,如下

@Bean
public MultipartConfigElement multipartConfigElement() {
    MultipartConfigFactory factory = new MultipartConfigFactory();
    //上傳的單個檔案最大值   KB,MB 這裡設定為10MB
    DataSize maxSize = DataSize.ofMegabytes(10);
    DataSize requestMaxSize = DataSize.ofMegabytes(30);
    factory.setMaxFileSize(maxSize);
    /// 設定一次上傳檔案的總大小
    factory.setMaxRequestSize(requestMaxSize);
    return factory.createMultipartConfig();
}

 這個方法可以放在啟動類裡面,也可以自己放置在一個配置類裡面,讓專案啟動的時候能正常載入就行。

2.檔案上傳

 單檔案上傳,我們需要用後端接受並將檔案儲存到專案裡面或者是自己定義路徑。這裡以圖片作為上傳的檔案。並且將檔案上傳到專案裡面。

@RestController
@RequestMapping("/file")
public class FileController {
    @PostMapping("/uploadFile")
    public String uploadFile(MultipartFile file, HttpServletRequest request)  {
        if (file.isEmpty()){
            return "上傳的檔案不能為空!請重新上傳";
        }
        if (file.getSize()<=0){
            return "上傳的檔案大小需要大於0kb";
        }
        System.out.println(file.getContentType());//image/png
        Date date = new Date();
        Long time = date.getTime();
        String originFileName = file.getOriginalFilename();//獲取檔案原始的名稱
        String newFileName = time+originFileName;
        //獲取專案執行的絕對路徑
        String filePath = System.getProperty("user.dir");

        //由於我是建立的多模組專案,所以獲取到的專案執行路徑為外層的專案路徑,
        // 這時候我們就需要在專案相對路徑這裡加上專案的名稱demo-upload
        String newFilePath = filePath+"\\demo-upload\\src\\main\\resources\\static\\images\\";

        //當然你也可以自己設定一個絕對路徑用於圖片上傳,檔案上傳。
        //比如說:D:\\images\\
        File file1 = new File(newFilePath);

        if (!file1.exists()){
            file1.mkdirs();
        }
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(newFilePath+newFileName);
            fileOutputStream.write(file.getBytes());
            fileOutputStream.flush();
            fileOutputStream.close();
            return "localhost:8095/images/"+newFileName;
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
        return "上傳失敗";
    }
}

程式碼說明:

 在程式碼裡,我們可以利用引數file來判斷這個檔案是否為空,或者將這個檔案的字尾名拿出來,判斷這個檔案的型別是否符合我們的要求,利用getContentType() 方法,如果你是上傳的png圖片,那麼打印出來的就是image/png 其他型別的圖片就是其他型別。我們為了區分圖片,可以利用當前時間的getTime方法獲得的數字來作為圖片的字首,也可以用其他的數字或者字串。都不想說了,碼字太累了。接下來獲取當前專案執行的路徑,由於我是建立的多模組專案,所以這個獲取的路徑需要再加上專案名稱,後面加上我們需要上傳的檔案儲存的位置,一般在resources檔案下面。然後判斷這個儲存檔案的資料夾是否存在,如果不存在就需要建立一個檔案。然後利用位元組流,將資料寫到檔案中,返回可訪問的路徑。

 前端程式碼,我直接在static目錄下面建立了一個upload.html檔案,然後我們在檔案裡面寫入一下內容

<p>單檔案上傳</p>
<form action="/file/uploadFile" method="POST" enctype="multipart/form-data">
    檔案:<input type="file" name="file"/>
    <input type="submit" />
</form>

 它的action對應了我們controller裡面訪問上傳檔案的對應的方法的路徑,method屬性是post,與後端一致。type為file的input框的name屬性需要與controller裡面的接受物件MultipartFile 一致,如果不一致的話後端無法接受到資料。如果你已經寫好後端,而前端後端引數不一致,你可以給後端引數加上一個註解。@RequestParam("file") 這個註解放在MultipartFile的前面,這樣即使你的引數名字不是file,也能正確接受到資料。

 將檔案上傳之後,那個返回的路徑應該是不能直接訪問到圖片的,會顯示404,我們需可以新增以下配置。

@Configuration
public class ResourceConfigAdapter implements WebMvcConfigurer {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //獲取檔案的真實路徑
        String path = System.getProperty("user.dir")+"\\demo-upload\\src\\main\\resources\\static\\images\\";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            registry.addResourceHandler("/images/**").
                    addResourceLocations("file:" + path);
        }

    }
}

 這裡的java動態配置比利用的yml的配置更靈活,在知道檔案要儲存的位置的情況下,可以自己在yml檔案裡面加配置。然後我們執行專案,如下:

 上傳一張圖片,返回可訪問的路徑

 然後我們將這個URL複製到瀏覽器,執行,就能訪問圖片了。

 這是單檔案上傳,然後可能你需要做多檔案上傳,很簡單,後端做一個迴圈就行了,然後利用MultipartFile的陣列接受檔案,對前端做一點修改。

 @PostMapping("/uploadFiles")
public String uploadFiles(MultipartFile[] files,HttpServletRequest request) {
    StringBuilder paths = new StringBuilder();
    for (MultipartFile file:files) {
        //中間的程式碼和上面的一樣
        try {
            //這裡根據實際情況修改,可以用陣列
            paths.append("localhost:8095/images/"+newFileName+"\n");
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }
    return paths.toString();
}

 前端稍微修改一下

<p>多檔案上傳</p>

<form action="/file/uploadFiles" method="POST" enctype="multipart/form-data">
    檔案:<input type="file" name="files" multiple="multiple"/>
    <input type="submit"/>
</form>

 這就完成了多檔案的上傳,在上傳的時候你需要按住Ctrl鍵,然後選中多個檔案,就能上傳了。

3.總結

 本文講解了單檔案,多檔案上傳,然後對檔案的上傳限制條件與訪問添加了一些配置。如果你覺得本文對你有用,點個贊表示一下