1. 程式人生 > >Springboot2(11)輕鬆搞定檔案上傳

Springboot2(11)輕鬆搞定檔案上傳

原始碼地址

配置

預設情況下Spring Boot無需做任何配置也能實現檔案上傳的功能,但有可能因預設配置不符而導致檔案上傳失敗問題,所以瞭解相關配置資訊更有助於我們對問題的定位和修復;

# 是否支援批量上傳   (預設值 true)
spring.servlet.multipart.enabled: true
# 上傳檔案的臨時目錄 (linux的預設臨時目錄定時會被刪除會導致上傳失敗,儘量指定臨時目錄)
spring.servlet.multipart.location:
# 上傳檔案最大為 1M (預設值 1M 根據自身業務自行控制即可)
spring.servlet.multipart.max-file-size: 1MB
# 設定總上傳的資料大小 10M(預設值10M 根據自身業務自行控制即可)
spring.servlet.multipart.max-request-size: 1MB
# 檔案大小閾值,當大於這個閾值時將寫入到磁碟,否則存在記憶體中,(預設值0 一般情況下不用特意修改)
spring.servlet.multipart.file-size-threshold: 0

注意springboot2的max-file-size、max-request-size只支援大寫的KB、MB、GB

或者

增加Bean配置 ,當前類上需要加註解@Configuration,不然掃不到就不會起作用了。 一般配置就放在啟動類中就好

@Configuration
public class multipartConfig {
    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory
(); String location = System.getProperty("user.dir") + "/data/tmp"; File tmpFile = new File(location); if (!tmpFile.exists()) { tmpFile.mkdirs(); } DataSize maxFileSize = DataSize.of(1,DataUnit.MEGABYTES);//1M DataSize maxRequestSize = DataSize.
of(1,DataUnit.MEGABYTES);//1M factory.setLocation(location); factory.setMaxFileSize(maxFileSize); factory.setMaxRequestSize(maxRequestSize); return factory.createMultipartConfig(); } }

控制層

建立一個FileUploadController@PostMapping相關方法則是對應的單檔案上傳、多檔案上傳、BASE64編碼三種處理方式。

@RequestParam(“file”)此處的"file"對應的就是html 中 name=“file” 的 input 標籤,而將檔案真正寫入的還是藉助的commons-io中的FileUtils.copyInputStreamToFile(inputStream,file)

@Controller
@RequestMapping("/uploads")
@Slf4j
public class FileUploadController {

    /**
     * 單檔案上傳
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload1")
    @ResponseBody
    public Map<String, String> upload1(@RequestParam("file") MultipartFile file)
            throws IOException {
        log.info("[檔案型別] - [{}]", file.getContentType());
        log.info("[檔名稱] - [{}]", file.getOriginalFilename());
        log.info("[檔案大小] - [{}]", file.getSize());
        file.transferTo(new File("D:/Users/" + file.getOriginalFilename()));
        Map<String, String> result = new HashMap<>(16);
        result.put("contentType", file.getContentType());
        result.put("fileName", file.getOriginalFilename());
        result.put("fileSize", file.getSize() + "");
        return result;
    }

    /**
     * 多檔案上傳
     * @param files
     * @return
     * @throws IOException
     */
    @PostMapping("/upload2")
    @ResponseBody
    public List<Map<String, String>> upload2(@RequestParam("files") MultipartFile[] files)
            throws IOException {
        if (files == null || files.length == 0) {
            return null;
        }
        List<Map<String, String>> results = new ArrayList<>();
        for (MultipartFile file : files) {
            // TODO Spring Mvc 提供的寫入方式
            file.transferTo(new File("D:/Users/" + file.getOriginalFilename()));
            Map<String, String> map = new HashMap<>(16);
            map.put("contentType", file.getContentType());
            map.put("fileName", file.getOriginalFilename());
            map.put("fileSize", file.getSize() + "");
            results.add(map);
        }
        return results;
    }

    @PostMapping("/upload3")
    @ResponseBody
    public void upload2(String base64) throws IOException {
        // TODO BASE64 方式的 格式和名字需要自己控制
        // (如 png 圖片編碼後字首就會是 data:image/png;base64,)
        final File tempFile = new File("D:/Users/test.jpg");
        // TODO 防止有的傳了 data:image/png;base64, 有的沒傳的情況
        String[] d = base64.split("base64,");
        final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
        FileCopyUtils.copy(bytes, tempFile);
    }
}

上傳測試可以用postman,這不提供上傳頁面。
在這裡插入圖片描述