SpringBoot實(shí)現(xiàn)文件上傳功能
經(jīng)典的文件上傳
服務(wù)器處理上傳文件一般都是先在請(qǐng)求中讀取文件信息,然后改變名稱保存在服務(wù)器的臨時(shí)路徑下,最后保存到服務(wù)器磁盤中。本次以thymeleaf搭建demo,因此需要引入thymeleaf依賴庫。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.5.5</version>
</dependency>
如果使用的是gradle構(gòu)建的項(xiàng)目,需要修改build.gradle文件:
compile 'org.springframework.boot:spring-boot-starter-thymeleaf:2.5.5'
新建一個(gè)Action類負(fù)責(zé)處理上傳的文件:
@RestController
@RequestMapping("/upload/*")
public class UploadAction {
@PostMapping("/file")
public Object uploadHandler(HttpServletRequest request, String title, MultipartFile file) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("title", title);
resultMap.put("fileName", file.getName()); // 文件名
resultMap.put("originalFilename", file.getOriginalFilename()); // 原始名稱
resultMap.put("content-type", file.getContentType()); // 文件類型
resultMap.put("fileSize", file.getSize() / 1024 + "K"); // 文件大小
try {
// 保存文件
String uploadedFilePath = saveFile(request, file.getInputStream(), file.getOriginalFilename()
.substring(file.getOriginalFilename().lastIndexOf(".") + 1));
resultMap.put("uploadedFilePath", uploadedFilePath); // 文件大小
} catch (IOException e) {
System.err.println("error-path: /upload/file, message: " + e.getMessage());
}
return resultMap;
}
/**
* 保存上傳的文件到本地服務(wù)器
*
* @param request HttpServletRequest
* @param input 輸入流
* @param ext 文件擴(kuò)展名
* @return 文件路徑
* @throws IOException
*/
public String saveFile(HttpServletRequest request, InputStream input, String ext) throws IOException {
String realPath = request.getServletContext().getRealPath("/upload/file/"); // 取得服務(wù)器真實(shí)路徑
File file = new File(realPath);
if (!file.getParentFile().exists()) { // 目錄不存在
file.mkdirs(); // 創(chuàng)建多級(jí)目錄
}
String filePath = realPath + UUID.randomUUID() + "." + ext;
// 取的文件輸出流
OutputStream out = new FileOutputStream(filePath);
byte[] data = new byte[2048]; // 緩沖數(shù)組2KB
int len = 0; // 讀取字節(jié)長度
while ((len = input.read(data)) != -1) {
out.write(data, 0, len); // 文件寫入磁盤
}
if (input != null) {
input.close();
}
out.close();
return filePath;
}
}
在resources目錄下新建templates文件夾,在里面創(chuàng)建index.html文件作為項(xiàng)目首頁展示。
<!doctype HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>文件上傳測(cè)試</title>
<meta charset="UTF-8" />
</head>
<body>
<form action="/upload/file" method="post" enctype="multipart/form-data">
<span>標(biāo)題:</span>
<input type="text" name="title" /><br>
<span>文件:</span>
<input type="file" name="file" /><br>
<input type="submit" value="上傳" />
</form>
</body>
</html>
啟動(dòng)項(xiàng)目,直接訪問:http://localhost:8080/將進(jìn)入index.html頁面。

點(diǎn)擊上傳按鈕,文件將被保存到服務(wù)器磁盤中:

SpringBoot對(duì)上傳文件處理的簡(jiǎn)化
SpringBoot對(duì)FileUpload組件進(jìn)行了整合,在文件保存的時(shí)候可以避免直接操作IO流,通過配置文件的方式指定文件上傳的限制參數(shù)。修改application.yml文件:
server:
port: 8080
spring:
servlet:
multipart:
enabled: true # 啟用文件上傳
max-file-size: 1MB # 單文件上傳最大限制
max-request-size: 10MB # 文件上傳最大值
file-size-threshold: 10KB # 上傳文件達(dá)到多大時(shí)寫入磁盤
location: / # 臨時(shí)文件存儲(chǔ)位置
修改UploadAction,使用MultipartFile類的transferTo方法保存上傳文件。
@RestController
@RequestMapping("/upload/*")
public class UploadAction {
@PostMapping("/file")
public Object uploadHandler(HttpServletRequest request, String title, MultipartFile file) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("title", title);
resultMap.put("fileName", file.getName()); // 文件名
resultMap.put("originalFilename", file.getOriginalFilename()); // 原始名稱
resultMap.put("content-type", file.getContentType()); // 文件類型
resultMap.put("fileSize", file.getSize() / 1024 + "K"); // 文件大小
try {
// 保存文件
String etc = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
String serverPath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + request.getContextPath() + "/file/upload/";
String fileName = UUID.randomUUID() + "." + etc;
resultMap.put("filePath", serverPath + fileName); // 文件地址(服務(wù)器訪問地址)
// 文件保存再真實(shí)路徑下
File saveFile = new File(request.getServletContext().getRealPath("/file/upload/") + fileName);
if (!saveFile.getParentFile().exists()) { // 目錄不存在,創(chuàng)建目錄
saveFile.mkdirs();
}
file.transferTo(saveFile); // 保存上傳文件
} catch (IOException e) {
System.err.println("error-path: /upload/file, message: " + e.getMessage());
}
return resultMap;
}
}
訪問:http://localhost:8080/

點(diǎn)擊上傳按鈕:

在瀏覽器上訪問filePath,可以預(yù)覽上傳的文件:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
maven多profile 打包下 -P參和-D參數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了maven多profile 打包下 -P參和-D參數(shù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
web項(xiàng)目WEB-INF下沒有web.xml的解決方法
新手如果在web項(xiàng)目創(chuàng)建后WEB-INF下面沒有出現(xiàn)web.xml,怎么辦?別慌,沒有web.xml文件的原因是因?yàn)樵趧?chuàng)建web項(xiàng)目的時(shí)候沒有把創(chuàng)建web.xml勾上。這篇文章主要介紹了web項(xiàng)目WEB-INF下沒有web.xml的解決方法,需要的朋友可以參考下2022-12-12
基于Java多線程notify與notifyall的區(qū)別分析
本篇文章對(duì)Java中多線程notify與notifyall的區(qū)別進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05
Java應(yīng)用注冊(cè)成Windows服務(wù)實(shí)現(xiàn)自啟的教程詳解
這篇文章主要給大家介紹了Java應(yīng)用注冊(cè)成Windows服務(wù)實(shí)現(xiàn)自啟的教程,文中有詳細(xì)的代碼示例和圖文講解供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2024-02-02
JetBrains?發(fā)布下一代?IDE無比輕量幾秒就能啟動(dòng)干活
雖然?JetBrains?公司說?Fleet?的定位和目標(biāo)并不是代替其他?IDE,但個(gè)人覺得,?如果?Fleet?火起來了,其他?IDE?就會(huì)黯然失色,特別是多語言開發(fā)者,誰愿意裝多個(gè)?IDE?呢?到時(shí)候,可能?JetBrains?以后的所有?IDE?要一統(tǒng)江湖了2021-12-12
Java?HttpURLConnection使用方法與實(shí)例演示分析
這篇文章主要介紹了Java?HttpURLConnection使用方法與實(shí)例演示,HttpURLConnection一個(gè)抽象類是標(biāo)準(zhǔn)的JAVA接口,該類位于java.net包中,它提供了基本的URL請(qǐng)求,響應(yīng)等功能,下面我們來深入看看2023-10-10
ThreadLocal數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)原理解析
這篇文章主要為大家介紹了ThreadLocal數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10

