前言
來啦老鐵城榛!
筆者學習Spring Boot有一段時間了揪利,附上Spring Boot系列學習文章,歡迎取閱狠持、賜教:
- 5分鐘入手Spring Boot;
- Spring Boot數(shù)據(jù)庫交互之Spring Data JPA;
- Spring Boot數(shù)據(jù)庫交互之Mybatis;
- Spring Boot視圖技術;
- Spring Boot之整合Swagger;
- Spring Boot之junit單元測試踩坑;
- 如何在Spring Boot中使用TestNG;
- Spring Boot之整合logback日志;
- Spring Boot之整合Spring Batch:批處理與任務調度;
- Spring Boot之整合Spring Security: 訪問認證;
- Spring Boot之整合Spring Security: 授權管理;
- Spring Boot之多數(shù)據(jù)庫源:極簡方案;
- Spring Boot之使用MongoDB數(shù)據(jù)庫源;
- Spring Boot之多線程疟位、異步:@Async;
- Spring Boot之前后端分離(一):Vue前端;
- Spring Boot之前后端分離(二):后端、前后端集成;
- Spring Boot之前后端分離(三):登錄喘垂、登出甜刻、頁面認證;
- Spring Boot之面向切面編程:Spring AOP;
- Spring Boot之集成Redis(一):Redis初入門;
- Spring Boot之集成Redis(二):集成Redis;
- Spring Boot之集成Redis(三):Spring Cache + Redis;
Redis挖了好大一個坑,肝了好幾天正勒,Redis暫時就學到這吧得院,今天我們來學點輕松的!
最近換電腦章贞,需要把舊電腦上的一些資料傳到新電腦尿招,很多人是將舊電腦的資料上傳到云盤,然后新電腦再從云盤下載阱驾,這個過程本沒有問題,我也經(jīng)常這么干怪蔑,但問題是云盤上傳文件的速度跟蝸牛爬一樣里覆,于是有了今天這一說:
-
Spring Boot之文件上傳、下載
項目代碼已上傳Git Hub倉庫缆瓣,歡迎取閱:
整體步驟
- 添加文件限制配置或編寫文件限制配置類喧枷;
- 編寫演示用文件上傳API;
- 編寫演示用文件下載API弓坞;
- 文件上傳隧甚、下載演示;
1. 添加文件限制配置或編寫文件限制配置類渡冻;
Spring Boot的默認單次上傳文件的大小為10 MB戚扳,在沒有額外干預的情況下,上傳超過10 MB的文件族吻,會有類似這樣的報錯:
org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
at org.apache.tomcat.util.http.fileupload.impl.FileItemStreamImpl$1.raiseError(FileItemStreamImpl.java:114)
at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.checkLimit(LimitedInputStream.java:76)
at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:135)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:98)
at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:291)
at org.apache.catalina.connector.Request.parseParts(Request.java:2869)
at org.apache.catalina.connector.Request.getParts(Request.java:2771)
at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098)
我們可以通過2種方式將這一限制擴大帽借。
1). 添加文件限制配置方式;
這個方式很簡單超歌,比如我們想將文件限制放大到10 GB砍艾,只需要在application.properties文件中添加以下類似配置即可:
#單個文件大小限制
spring.servlet.multipart.max-file-size=10240MB
#單個請求,文件總大小限制
spring.servlet.multipart.max-request-size=10240MB
application.properties文件整體樣子:
server.port=8080
#單個文件大小限制
spring.servlet.multipart.max-file-size=10240MB
#單個請求巍举,文件大小限制
spring.servlet.multipart.max-request-size=10240MB
#默認文件上傳功能脆荷,文件保存的根目錄
file.upload.dir=E:\\Resource\\spring-boot-cloud\\
#默認文件下載功能,文件保存的根目錄
file.download.dir=E:\\Resource\\spring-boot-cloud\\
2). 編寫文件限制配置類方式;
這種方式也加單蜓谋,新建config包梦皮,在包內(nèi)創(chuàng)建一個MultipartConfig.java類(名字不限),類中寫入以下代碼:
package com.github.dylanz666.config;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize;
import javax.servlet.MultipartConfigElement;
/**
* @author : dylanz
* @since : 11/02/2020
*/
@Configuration
public class MultipartConfig {
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory multipartConfigFactory = new MultipartConfigFactory();
multipartConfigFactory.setMaxFileSize(DataSize.parse("10240MB"));
multipartConfigFactory.setMaxRequestSize(DataSize.parse("10240MB"));
return multipartConfigFactory.createMultipartConfig();
}
}
2種方式效果一樣孤澎,任君選擇届氢!
2. 編寫演示用文件上傳API;
package com.github.dylanz666.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
/**
* @author : dylanz
* @since : 11/02/2020
*/
@RestController
@RequestMapping("/api")
public class FileUploadController {
@Value(value = "${file.upload.dir}")
private String rootPath;
@GetMapping("/upload/ping")
public String ping() {
return "success";
}
@PostMapping("/file")
public Boolean upload(@RequestParam("file") MultipartFile file) {
try {
String fileName = file.getOriginalFilename();
assert fileName != null;
System.out.println(fileName);
File dest = new File(rootPath, fileName);
file.transferTo(dest);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
3. 編寫演示用文件下載API覆旭;
為了系統(tǒng)學習文件上傳與下載退子,我又實現(xiàn)了一個文件下載的API。
新建FileDownloadController.java類型将,寫入代碼:
package com.github.dylanz666.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Objects;
/**
* @author : dylanz
* @since : 11/08/2020
*/
@RestController
@RequestMapping("/api")
public class FileDownloadController {
@Value(value = "${file.download.dir}")
private String rootPath;
private FileInputStream fis = null;
private BufferedInputStream bis = null;
@GetMapping("/download/ping")
public String ping() {
return "success";
}
@GetMapping("/file")
public String download(@RequestParam String fileName) {
try {
File file = new File(rootPath, fileName);
HttpServletResponse response = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
assert response != null;
response.setContentType("application/force-download");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
if (file.exists()) {
byte[] buffer = new byte[1024];
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
}
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
} finally {
try {
bis.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4. 文件上傳寂祥、下載演示;
1). 文件上傳:
上傳前:
上傳:
上傳后:
咱們來稍微解讀一下:
(1). 由于我要快速實現(xiàn)上傳接口七兜,用于傳文件丸凭,所以我沒有做過多的驗證和邏輯處理,關鍵代碼只有3行:
String fileName = file.getOriginalFilename();
File dest = new File(rootPath + fileName);
file.transferTo(dest);
即API拿到傳來的文件腕铸,拿其文件名惜犀,拼出服務器的文件路徑,保存就完事了狠裹!
(2). 我們可以在application.properties自定義一個默認的上傳文件保存根目錄虽界,然后用@Value注解引用進項目,如:
@Value(value = "${file.upload.dir}")
private String rootPath;
(3). 文件上傳還是挺快的涛菠,經(jīng)試驗莉御,2G的文件約600秒完成上傳,平均3.4 MB/s俗冻,況且我們省去了下載的動作礁叔,相比于上傳到云盤,再下載到新電腦的方式迄薄,簡直是太快了琅关!
(4). 上傳的速度應該受我局域網(wǎng)設備(路由器)、局域網(wǎng)帶寬等的限制讥蔽,但即使這樣死姚,速度也是比云盤那種方式快多了,而且速度十分穩(wěn)定勤篮!
2). 文件下載:
(文件下載的功能是我們自己學習用的都毒,與本次解決換電腦文件傳輸慢的問題無關。)
由于我們寫的是GET API碰缔,可在瀏覽器直接訪問下載API账劲,如:http://192.168.0.105:8080/api/file?fileName=Postman-win64-7.32.0-Setup.exe
速度也是賊快哦!
至此,我們在Spring Boot項目中實現(xiàn)了文件的上傳瀑焦、下載腌且,整個過程非常輕松,可謂絲滑榛瓮,讀者可自行擴展铺董,如批量文件上傳、下載等禀晓。
而經(jīng)過此次的學習精续,我想我知道怎么做一個個人網(wǎng)盤了,你呢粹懒?
如果本文對您有幫助重付,麻煩點贊、關注凫乖!
謝謝确垫!