spring-mvc之檔案上傳與下載
阿新 • • 發佈:2021-07-05
配置
spring-boot中,起步依賴自動添加了需要的庫,並自動配置了
MultipartResolver
解析器,所以這步只針對直接使用spring的情況
spring-webmvc基於Apache提供的2個庫實現檔案的上傳與下載
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
配置MultipartResolver元件
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
檔案上傳
官方文件參考
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-multipart-forms
Spring中檔案上傳的核心是使用 MultipartFile
型別的引數接收檔案資料。
MultipartFile
提供了以下常用方法
boolean isEmpty()
- 判斷表單檔案是否為空String getOriginalFilename();
- 獲取檔名String getContentType()
- 獲取檔案型別long getSize()
- 獲取檔案大小byte[] getBytes()
- 將檔案轉換為位元組陣列InputStream getInputStream()
- 將檔案轉換為輸入流void transferTo(File dest)
- 檔案儲存的快捷方式void transferTo(Path dest)
另外,spring-boot檔案上傳預設配置中,單檔案限制大小為1MB,單次請求檔案總大小限制為10MB,可以使用以下方式修改預設值
spring:
servlet:
multipart:
enabled: true
max-file-size: 2MB # 單檔案大小限制
max-request-size: 10MB # 檔案總大小限制
單檔案上傳示例
HTML表單
<form action="/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">上傳</button>
</form>
控制器程式碼
@PostMapping("/file/upload")
@ResponseBody
public String uploadFile(@RequestParam("file")MultipartFile file)
{
if(!file.isEmpty())
{
String fileName=file.getOriginalFilename();
String basePath="/home/lyp/Projects/spring-boot/web/src/main/resources/res";
try
{
File f=new File(basePath,fileName);
file.transferTo(f);
return "上傳成功";
}
catch(IOException e)
{
e.printStackTrace();
}
}
return "上傳失敗";
}
多檔案上傳示例
HTML表單
<form action="/files/upload" method="post" enctype="multipart/form-data">
<input type="file" name="files" multiple>
<button type="submit">上傳</button>
</form>
控制器中只需要接收MultipartFile
陣列或List即可
@PostMapping("/files/upload")
@ResponseBody
public String uploadFiles(@RequestParam("files") List<MultipartFile> files)
{
String basePath = "/home/lyp/Projects/spring-boot/web/src/main/resources/res";
try
{
for(MultipartFile file: files)
{
if(!file.isEmpty())
{
String fileName = file.getOriginalFilename();
File f = new File(basePath,fileName);
file.transferTo(f);
}
}
return "上傳成功";
}
catch(IOException e)
{
e.printStackTrace();
}
return "上傳失敗";
}
檔案下載
使用Servlet相關的API即可,唯一需要注意的是設定響應頭資訊
這裡測試圖片在res目錄下,客戶端之所以直接從根路徑訪問而不用加res字首,是因為額外將res目錄配置到spring-boot的靜態資源查詢路徑中了。
配置方法就是使用static-locations
選項。
HTML程式碼
<img src="/test.png" alt="">
<a href="/file/download?filename=test.png">下載</a>
控制器程式碼
@GetMapping("/file/download")
@ResponseBody
public String download(@RequestParam("filename") String filename,
HttpServletResponse resp)
{
if(filename!=null && !filename.isBlank())
{
String basePath = "/home/lyp/Projects/spring-boot/web/src/main/resources/res";
File file=new File(basePath,filename);
if(file.exists())
{
resp.setContentType("application/forc-download");
resp.setHeader("Content-Disposition","attachment;filename="+filename);
try(ServletOutputStream out=resp.getOutputStream();)
{
Path path=Path.of(file.toURI());
byte[] bytes = Files.readAllBytes(path);
out.write(bytes);
out.flush();
return "下載成功";
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
return "下載失敗";
}