Springboot文件上傳功能的實現(xiàn)
1.新建文件上傳頁面
在static目錄中新建upload-test.html,上傳頁面代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>springboot文件上傳測試</title>
</head>
<body>
<form action="/uploadFile" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="文件上傳" />
</form>
</body>
</html>
其中后端處理文件上傳的請求地址為/uploadFile,請求方法為POST。在文件上傳時需要設置form表單的enctype屬性為“multipart/form-data”。
效果圖如下:

2.新建文件上傳處理Controller類
在controller包下新建UploadController類并編寫實際的文件上傳邏輯代碼,如下所示:
package ltd.newbee.mall.controller;
import ltd.newbee.mall.util.PageResult;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
@Controller
public class UploadController {
//文件保存路徑為在D盤下的upload文件夾,可以按照自己的習慣修改
private final static String FILE_UPLOAD_PATH = "D:\\upload\\";
@RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
@ResponseBody
public String uploadFile(@RequestParam("file") MultipartFile file){
if (file.isEmpty()){
return "文件上傳失敗";
}
String fileName = file.getOriginalFilename();
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//生成文件名稱通用方法
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
Random r = new Random();
StringBuilder tempName = new StringBuilder();
tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
String newFileName = tempName.toString();
try {
//保存文件
byte[] bytes = file.getBytes();
Path path = Paths.get(FILE_UPLOAD_PATH+newFileName);
Files.write(path,bytes);
}catch (IOException e){
e.printStackTrace();
}
return "上傳成功";
}
}
由于Spring Boot已經(jīng)自動配置了StandardServletMultipartResolver類來處理文件上傳請求,因此能夠直接在控制器方法中使用MultipartFile讀取文件信息。 @RequestParam中文件名稱屬性需要與前端頁面中input文件輸入框設置的name屬性一致。如果文件為空則返回上傳失敗,如果不為空則根據(jù)日期生成一個新的文件名,讀取文件流程并寫入指定的路徑中,最后返回上傳成功的提示信息。
需要注意的是文件上傳路徑的設置。在上述代碼中設置的文件保存路徑為D:\upload\,即在D盤下的upload文件夾。如果項目部署在Linux系統(tǒng)中的話,寫法與此不同。比如想要把文件上傳到/opt/newbee/upload目錄下,就需要把路徑設置的代碼改為private final static String FILE_UPLOAD_PATH = “/opt/newbee/upload/”。這一點需要注意,兩種系統(tǒng)的寫法存在一些差異。如果文件存儲目錄還沒有創(chuàng)建的話,首先需要創(chuàng)建該目錄,然后啟動項目進行文件上傳測試。
3.文件上傳功能測試
在編碼完成后,啟動Spring Boot項目。在啟動成功后,打開瀏覽器并輸入測試頁面地址:
http://localhost:8080/upload-test.html
打開后選擇上傳的文件,然后上傳,顯示成功。

檢查本機upload目錄下是否有改文件(注意這里需要在對應的位置建立好upload文件夾)

另外,在Spring Boot項目中支持單個文件的最大值默認為1MB,支持單個請求最大值默認10 MB。如果選擇了大于默認值的文件進行上傳,比如一個1.2MB的文件或者一個11MB的請求,就會報錯。
4.文件上傳路徑回顯
Spring Boot項目與普通Spring項目的目錄結構不同,并沒有webapp目錄,因此無法與普通的Java Web項目一樣,上傳文件到webapp目錄中并直接根據(jù)目錄進行訪問。Spring Boot項目中通常使用自定義靜態(tài)資源映射目錄,以此來實現(xiàn)文件上傳整個流程的閉環(huán)。比如在前文文件上傳案例中,在文件上傳到upload目錄后,會增加一個自定義靜態(tài)資源映射配置,使得在upload下的靜態(tài)資源可以通過該映射地址被訪問到。
新建config包并在config包中新增SpringBootWebMvcConfigurer類,實現(xiàn)代碼如下所示:
package ltd.newbee.mall.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SpringBootWebMvcConfigurer implements WebMvcConfigurer {
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/upload/**").addResourceLocations("file:D:\\upload\\");
}
}
通過以上代碼配置,所有以“/upload/”開頭的靜態(tài)資源在請求時都會映射到D盤的upload目錄下。路徑的設置與前文中上傳文件的設置目錄類似,不同系統(tǒng)的文件路徑的寫法不同(比如Linux和Windows)。同時需要注意在設置靜態(tài)資源映射路徑時,路徑前需要添加“file:”前綴。
最后修改一下在文件上傳時的返回信息,把路徑拼裝好并返回到頁面上,以便于功能測試,UploadController代碼的修改如下所示:
return "上傳成功,地址為:/upload/"+newFileName;
最后啟動項目進行測試

檢查對應目錄下是否有文件

上傳成功完成。
5.多文件上傳功能實現(xiàn)
首先,在static目錄中新建upload-same-file-name.html,頁面代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上傳測試(文件名相同)</title>
</head>
<body>
<form action="/uploadFilesBySameName" method="post" enctype="multipart/form-data">
<input type="file" name="files"/><br><br>
<input type="file" name="files"/><br><br>
<input type="file" name="files"/><br><br>
<input type="file" name="files"/><br><br>
<input type="file" name="files"/><br><br>
<input type="submit" value="文件上傳"/>
</form>
</body>
</html>
多文件上傳頁面與單文件上傳頁面類似,不同點是新增了4個文件輸入框,文件輸入框的name屬性統(tǒng)一命名為files,文件名完全一致。后端處理文件上傳的請求地址為/uploadFilesBySameName,請求方法為POST。
在UploadController類中新增uploadFilesBySameName()方法,用于處理在文件名相同時的多文件上傳問題,新增代碼如下所示:
@RequestMapping(value = "/uploadFileBySameName",method = RequestMethod.POST)
@ResponseBody
public String uploadFileBySameName(@RequestPart MultipartFile[] files){
if (files == null|| files.length==0){
return "參數(shù)錯誤";
}
if (files.length>5){
return "文件最多上傳5個";
}
String uploadResult = "上傳成功,地址為:<br>";
for (MultipartFile file:files){
String fileName = file.getOriginalFilename();
if (StringUtils.isEmpty(fileName)){
//表示無文件信息,跳出當前循環(huán)
continue;
}
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//生成文件名稱的通用方法
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
Random r = new Random();
StringBuilder tempName = new StringBuilder();
tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
String newFileName = tempName.toString();
try {
//保存文件
byte[] bytes = file.getBytes();
Path path = Paths.get(FILE_UPLOAD_PATH+newFileName);
Files.write(path,bytes);
uploadResult += "/upload/" + newFileName + "<br>";
}catch (IOException e){
e.printStackTrace();
}
}
return uploadResult;
}
與單文件在上傳時的uploadFile()方法相比,多文件上傳有兩處改動。
第一,文件參數(shù)在接收時的代碼改動。在多文件上傳并接收參數(shù)時使用的是@RequestPart注解,且接收的文件參數(shù)是一個數(shù)組MultipartFile。而單文件在上傳時使用的是@RequestParam注解,接收的文件是單個對象。
第二,文件在保存時增加循環(huán)邏輯。多文件保存的處理方式與單文件在上傳時比較類似,只是增加了循環(huán)邏輯,對接收的MultipartFile數(shù)組中每一個文件進行存儲操作,最后拼接文件的地址信息并返回。
另外一個需要注意的知識點,多文件上傳在接收參數(shù)時,參數(shù)名稱files需要完全對應input框中的name屬性。比如本次演示,在upload-same-file-name.html文件中所有文件輸入框的name屬性都是files;在后端處理時,uploadFilesBySameName()方法的參數(shù)名稱也定義為files,兩個名稱是對應的。如果所有文件輸入框的name屬性都改為uploadFiles,那么uploadFilesBySameName()方法的參數(shù)名稱也需要改為uploadFiles,否則接收的文件對象數(shù)組為空。
在編碼完成后,啟動Spring Boot項目。在在啟動成功后打開瀏覽器并輸入多圖上傳的測試頁面地址:
http://localhost:8080/upload-same-file-name.html
實際效果:


6.文件名不同時的多文件上傳處理
首先,在static目錄中新建upload-different-file-name.html,頁面代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上傳測試(文件名不同)</title>
</head>
<body>
<form action="/uploadFilesByDifferentName" method="post" enctype="multipart/form-data">
<input type="file" name="files1"/><br><br>
<input type="file" name="files2"/><br><br>
<input type="file" name="files3"/><br><br>
<input type="file" name="files4"/><br><br>
<input type="file" name="files5"/><br><br>
<input type="submit" value="文件上傳"/>
</form>
</body>
</html>
然后,在UploadController類中新增uploadFilesByDifferentName()方法,用于處理文件名在不相同時的多文件上傳,新增代碼如下所示:
@RequestMapping(value = "/uploadFilesByDifferentName",method = RequestMethod.POST)
@ResponseBody
public String uploadFilesByDifferentName(HttpServletRequest httpServletRequest Request){
List<MultipartFile> multipartFiles = new ArrayList<>(8);
//如果不是文件上傳請求則不處理
if (!standardServletMultipartResolver.isMultipart(httpServletRequest)){
return "請選擇文件";
}
//將HttpServletRequest 對象轉換為MultipartHttpServletRequest對象,并讀取文件
MultipartHttpServletRequest multiRequest =(MultipartHttpServletRequest)httpServletRequest;
Iterator<String> iter = multiRequest.getFileNames();
int total=0;
while (iter.hasNext()){
if (total>5) {
return "最多上傳5個文件";
}
total+=1;
MultipartFile file = multiRequest.getFile(iter.next());
multipartFiles.add(file);
}
if (CollectionUtils.isEmpty(multipartFiles)) {
return "請選擇文件";
}
if (multipartFiles != null && multipartFiles.size()>5){
return "文件最多上傳5個";
}
String uploadResult = "上傳成功,地址為:<br>";
for(int i=0;i<multipartFiles.size();i++){
String fileName = multipartFiles.get(i).getOriginalFilename();
if (StringUtils.isEmpty(fileName)){
//表示無文件信息,跳出當前循環(huán)
continue;
}
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//生成文件名稱的通用方法
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
Random r = new Random();
StringBuilder tempName = new StringBuilder();
tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
String newFileName = tempName.toString();
try {
//保存文件
byte[] bytes = multipartFiles.get(i).getBytes();
Path path = Paths.get(FILE_UPLOAD_PATH+newFileName);
Files.write(path,bytes);
uploadResult += "/upload/" + newFileName + "<br>";
}catch (IOException e){
e.printStackTrace();
}
}
return uploadResult;
}
與文件名相同時的多文件上傳的uploadFilesBySameName()方法相比,文件名不同時的改動只有一處,即文件參數(shù)在接收時的代碼做了改動。在讀取文件信息時的邏輯是自行實現(xiàn)的代碼邏輯,首先調(diào)用isMultipart()方法判斷當前請求是否為文件上傳請求,如果不是則不進行處理,如果是文件上傳請求,則HttpServletReques對象轉換為MultipartHttpServletRequest對象,并讀取文件數(shù)據(jù),在讀取完成后再依次進行存儲。存儲文件的過程與之前的邏輯一致,最后拼接文件的地址信息并返回。
另外,需要判斷當前請求是否為文件上傳請求時要用到StandardServletMultipart Resolver類isMultipart()方法。前文中提到的StandardServletMultipartResolver類已經(jīng)自動配置,所以可以直接在UploadController類中使用@Autowired注解注入,代碼如下所示:
@Autowired
private StandardServletMultipartResolver standardServletMultipartResolver;
測試成功

以上就是Springboot文件上傳功能的實現(xiàn)的詳細內(nèi)容,更多關于Springboot文件上傳的資料請關注腳本之家其它相關文章!
相關文章
java判斷l(xiāng)ist不為空的實現(xiàn),和限制條數(shù)不要在一起寫
這篇文章主要介紹了java判斷l(xiāng)ist不為空的實現(xiàn),和限制條數(shù)不要在一起寫。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
Spring?Boot?Admin?添加報警提醒和登錄驗證功能的具體實現(xiàn)
報警提醒功能是基于郵箱實現(xiàn)的,當然也可以使用其他的提醒功能,如釘釘或飛書機器人提醒也是可以的,但郵箱報警功能的實現(xiàn)成本最低,所以本文我們就來看郵箱的報警提醒功能的具體實現(xiàn)2022-01-01

