上傳檔案應該是最經常遇到的場景,今天就來和大家一起來簡單做一個Spring Boot上傳檔案的功能,廢話不多說,直接開始。
專案結構,如下圖:
pom 依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
上傳控制類
@Controller
public class UploadController
{
private static String UPLOADED_FOLDER = "D:\\uploadFile\\";
@GetMapping("/")
public String index()
{
return "upload";
}
@PostMapping("/upload")
public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes)
{
if (file.isEmpty())
{
redirectAttributes.addFlashAttribute("message", "請選擇檔案上傳");
return "redirect:uploadStatus";
}
try
{
byte[] bytes = file.getBytes();
Path dir = Paths.get(UPLOADED_FOLDER);
Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
if (!Files.exists(dir))
{
Files.createDirectories(dir);
}
Files.write(path, bytes);
redirectAttributes.addFlashAttribute("message","上傳成功,檔案的名稱:" + file.getOriginalFilename());
}
catch (IOException e)
{
redirectAttributes.addFlashAttribute("message", "服務異常");
e.printStackTrace();
}
return "redirect:/uploadStatus";
}
@GetMapping("/uploadStatus")
public String uploadStatus()
{
return "uploadStatus";
}
}
通過MultipartFile
讀取檔案資訊,如果檔案為空跳轉到結果頁並給出提示;如果不為空讀取檔案流並寫入到指定目錄,最後將結果展示到頁面。
MultipartFile
是Spring上傳檔案的封裝類,包含了檔案的二進位制流和檔案屬性等資訊,在配置檔案中也可對相關屬性進行配置。
spring.http.multipart.enabled=true
#預設支援檔案上傳.spring.http.multipart.file-size-threshold=0
#支援檔案寫入磁碟.spring.http.multipart.location=
# 上傳檔案的臨時目錄spring.http.multipart.max-file-size=1Mb
# 最大支援檔案大小spring.http.multipart.max-request-size=10Mb
# 最大支援請求大小
最常用的是最後兩個配置內容,限制檔案上傳大小,上傳時超過大小會丟擲異常。
配置檔案
application.properties
server.port=8086
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
異常處理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MultipartException.class)
public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
return "redirect:/uploadStatus";
}
}
設定一個@ControllerAdvice
用來監控Multipart
上傳的檔案大小是否受限,當出現此異常時在前端頁面給出提示。
前端頁面
upload.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<h1>上傳檔案</h1>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="file" /><br/><br/>
<input type="submit" value="Submit" />
</form>
</body>
</html>
uploadStatus.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<h1>上傳狀態</h1>
<div th:if="${message}">
<h2 th:text="${message}"/>
</div>
</body>
</html>
測試
- 啟動專案,瀏覽器輸入
localhost:8086
,顯示如下:
- 選擇檔案進行上傳,這裡我選擇了一張圖片
- 點選
Submit
,顯示上傳成功。
- 檢視本地資料夾
D:\\uploadFile\\
中已經有了該圖片,至此該上傳功能已實現。
大檔案上傳
- 測試一下,超過設定的
10M
的檔案上傳結果,如下圖,上傳檔案大於10M出現連線重置的問題,此異常內容 GlobalException 也捕獲不到。
Tomcat連線重置
如果部署到Tomcat,請配置maxSwallowSize以避免此Tomcat連線重置問題。 對於嵌入式Tomcat,宣告一個TomcatEmbeddedServletContainerFactory,如下程式碼:
package com.cy;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringbootUploadApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringbootUploadApplication.class, args);
}
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
//-1 means unlimited
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return tomcat;
}
}
再次上傳超過大小限制的檔案,頁面丟擲異常如下:
總結
關於springboot上傳檔案簡單的demo完成了,還有多檔案上傳,小夥伴們也可以自己去試試。