Springboot文件上傳功能的實(shí)現(xiàn)
1.新建文件上傳頁面
在static目錄中新建upload-test.html,上傳頁面代碼如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>springboot文件上傳測(cè)試</title> </head> <body> <form action="/uploadFile" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="submit" value="文件上傳" /> </form> </body> </html>
其中后端處理文件上傳的請(qǐng)求地址為/uploadFile,請(qǐng)求方法為POST。在文件上傳時(shí)需要設(shè)置form表單的enctype屬性為“multipart/form-data”。
效果圖如下:
2.新建文件上傳處理Controller類
在controller包下新建UploadController類并編寫實(shí)際的文件上傳邏輯代碼,如下所示:
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文件夾,可以按照自己的習(xí)慣修改 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)自動(dòng)配置了StandardServletMultipartResolver類來處理文件上傳請(qǐng)求,因此能夠直接在控制器方法中使用MultipartFile讀取文件信息。 @RequestParam中文件名稱屬性需要與前端頁面中input文件輸入框設(shè)置的name屬性一致。如果文件為空則返回上傳失敗,如果不為空則根據(jù)日期生成一個(gè)新的文件名,讀取文件流程并寫入指定的路徑中,最后返回上傳成功的提示信息。
需要注意的是文件上傳路徑的設(shè)置。在上述代碼中設(shè)置的文件保存路徑為D:\upload\,即在D盤下的upload文件夾。如果項(xiàng)目部署在Linux系統(tǒng)中的話,寫法與此不同。比如想要把文件上傳到/opt/newbee/upload目錄下,就需要把路徑設(shè)置的代碼改為private final static String FILE_UPLOAD_PATH = “/opt/newbee/upload/”。這一點(diǎn)需要注意,兩種系統(tǒng)的寫法存在一些差異。如果文件存儲(chǔ)目錄還沒有創(chuàng)建的話,首先需要?jiǎng)?chuàng)建該目錄,然后啟動(dòng)項(xiàng)目進(jìn)行文件上傳測(cè)試。
3.文件上傳功能測(cè)試
在編碼完成后,啟動(dòng)Spring Boot項(xiàng)目。在啟動(dòng)成功后,打開瀏覽器并輸入測(cè)試頁面地址:
http://localhost:8080/upload-test.html
打開后選擇上傳的文件,然后上傳,顯示成功。
檢查本機(jī)upload目錄下是否有改文件(注意這里需要在對(duì)應(yīng)的位置建立好upload文件夾)
另外,在Spring Boot項(xiàng)目中支持單個(gè)文件的最大值默認(rèn)為1MB,支持單個(gè)請(qǐng)求最大值默認(rèn)10 MB。如果選擇了大于默認(rèn)值的文件進(jìn)行上傳,比如一個(gè)1.2MB的文件或者一個(gè)11MB的請(qǐng)求,就會(huì)報(bào)錯(cuò)。
4.文件上傳路徑回顯
Spring Boot項(xiàng)目與普通Spring項(xiàng)目的目錄結(jié)構(gòu)不同,并沒有webapp目錄,因此無法與普通的Java Web項(xiàng)目一樣,上傳文件到webapp目錄中并直接根據(jù)目錄進(jìn)行訪問。Spring Boot項(xiàng)目中通常使用自定義靜態(tài)資源映射目錄,以此來實(shí)現(xiàn)文件上傳整個(gè)流程的閉環(huán)。比如在前文文件上傳案例中,在文件上傳到upload目錄后,會(huì)增加一個(gè)自定義靜態(tài)資源映射配置,使得在upload下的靜態(tài)資源可以通過該映射地址被訪問到。
新建config包并在config包中新增SpringBootWebMvcConfigurer類,實(shí)現(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)資源在請(qǐng)求時(shí)都會(huì)映射到D盤的upload目錄下。路徑的設(shè)置與前文中上傳文件的設(shè)置目錄類似,不同系統(tǒng)的文件路徑的寫法不同(比如Linux和Windows)。同時(shí)需要注意在設(shè)置靜態(tài)資源映射路徑時(shí),路徑前需要添加“file:”前綴。
最后修改一下在文件上傳時(shí)的返回信息,把路徑拼裝好并返回到頁面上,以便于功能測(cè)試,UploadController代碼的修改如下所示:
return "上傳成功,地址為:/upload/"+newFileName;
最后啟動(dòng)項(xiàng)目進(jìn)行測(cè)試
檢查對(duì)應(yīng)目錄下是否有文件
上傳成功完成。
5.多文件上傳功能實(shí)現(xiàn)
首先,在static目錄中新建upload-same-file-name.html,頁面代碼如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>多文件上傳測(cè)試(文件名相同)</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>
多文件上傳頁面與單文件上傳頁面類似,不同點(diǎn)是新增了4個(gè)文件輸入框,文件輸入框的name屬性統(tǒng)一命名為files,文件名完全一致。后端處理文件上傳的請(qǐng)求地址為/uploadFilesBySameName,請(qǐng)求方法為POST。
在UploadController類中新增uploadFilesBySameName()方法,用于處理在文件名相同時(shí)的多文件上傳問題,新增代碼如下所示:
@RequestMapping(value = "/uploadFileBySameName",method = RequestMethod.POST) @ResponseBody public String uploadFileBySameName(@RequestPart MultipartFile[] files){ if (files == null|| files.length==0){ return "參數(shù)錯(cuò)誤"; } if (files.length>5){ return "文件最多上傳5個(gè)"; } String uploadResult = "上傳成功,地址為:<br>"; for (MultipartFile file:files){ String fileName = file.getOriginalFilename(); if (StringUtils.isEmpty(fileName)){ //表示無文件信息,跳出當(dāng)前循環(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; }
與單文件在上傳時(shí)的uploadFile()方法相比,多文件上傳有兩處改動(dòng)。
第一,文件參數(shù)在接收時(shí)的代碼改動(dòng)。在多文件上傳并接收參數(shù)時(shí)使用的是@RequestPart注解,且接收的文件參數(shù)是一個(gè)數(shù)組MultipartFile。而單文件在上傳時(shí)使用的是@RequestParam注解,接收的文件是單個(gè)對(duì)象。
第二,文件在保存時(shí)增加循環(huán)邏輯。多文件保存的處理方式與單文件在上傳時(shí)比較類似,只是增加了循環(huán)邏輯,對(duì)接收的MultipartFile數(shù)組中每一個(gè)文件進(jìn)行存儲(chǔ)操作,最后拼接文件的地址信息并返回。
另外一個(gè)需要注意的知識(shí)點(diǎn),多文件上傳在接收參數(shù)時(shí),參數(shù)名稱files需要完全對(duì)應(yīng)input框中的name屬性。比如本次演示,在upload-same-file-name.html文件中所有文件輸入框的name屬性都是files;在后端處理時(shí),uploadFilesBySameName()方法的參數(shù)名稱也定義為files,兩個(gè)名稱是對(duì)應(yīng)的。如果所有文件輸入框的name屬性都改為uploadFiles,那么uploadFilesBySameName()方法的參數(shù)名稱也需要改為uploadFiles,否則接收的文件對(duì)象數(shù)組為空。
在編碼完成后,啟動(dòng)Spring Boot項(xiàng)目。在在啟動(dòng)成功后打開瀏覽器并輸入多圖上傳的測(cè)試頁面地址:
http://localhost:8080/upload-same-file-name.html
實(shí)際效果:
6.文件名不同時(shí)的多文件上傳處理
首先,在static目錄中新建upload-different-file-name.html,頁面代碼如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>多文件上傳測(cè)試(文件名不同)</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()方法,用于處理文件名在不相同時(shí)的多文件上傳,新增代碼如下所示:
@RequestMapping(value = "/uploadFilesByDifferentName",method = RequestMethod.POST) @ResponseBody public String uploadFilesByDifferentName(HttpServletRequest httpServletRequest Request){ List<MultipartFile> multipartFiles = new ArrayList<>(8); //如果不是文件上傳請(qǐng)求則不處理 if (!standardServletMultipartResolver.isMultipart(httpServletRequest)){ return "請(qǐng)選擇文件"; } //將HttpServletRequest 對(duì)象轉(zhuǎn)換為MultipartHttpServletRequest對(duì)象,并讀取文件 MultipartHttpServletRequest multiRequest =(MultipartHttpServletRequest)httpServletRequest; Iterator<String> iter = multiRequest.getFileNames(); int total=0; while (iter.hasNext()){ if (total>5) { return "最多上傳5個(gè)文件"; } total+=1; MultipartFile file = multiRequest.getFile(iter.next()); multipartFiles.add(file); } if (CollectionUtils.isEmpty(multipartFiles)) { return "請(qǐng)選擇文件"; } if (multipartFiles != null && multipartFiles.size()>5){ return "文件最多上傳5個(gè)"; } String uploadResult = "上傳成功,地址為:<br>"; for(int i=0;i<multipartFiles.size();i++){ String fileName = multipartFiles.get(i).getOriginalFilename(); if (StringUtils.isEmpty(fileName)){ //表示無文件信息,跳出當(dāng)前循環(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; }
與文件名相同時(shí)的多文件上傳的uploadFilesBySameName()方法相比,文件名不同時(shí)的改動(dòng)只有一處,即文件參數(shù)在接收時(shí)的代碼做了改動(dòng)。在讀取文件信息時(shí)的邏輯是自行實(shí)現(xiàn)的代碼邏輯,首先調(diào)用isMultipart()方法判斷當(dāng)前請(qǐng)求是否為文件上傳請(qǐng)求,如果不是則不進(jìn)行處理,如果是文件上傳請(qǐng)求,則HttpServletReques對(duì)象轉(zhuǎn)換為MultipartHttpServletRequest對(duì)象,并讀取文件數(shù)據(jù),在讀取完成后再依次進(jìn)行存儲(chǔ)。存儲(chǔ)文件的過程與之前的邏輯一致,最后拼接文件的地址信息并返回。
另外,需要判斷當(dāng)前請(qǐng)求是否為文件上傳請(qǐng)求時(shí)要用到StandardServletMultipart Resolver類isMultipart()方法。前文中提到的StandardServletMultipartResolver類已經(jīng)自動(dòng)配置,所以可以直接在UploadController類中使用@Autowired注解注入,代碼如下所示:
@Autowired private StandardServletMultipartResolver standardServletMultipartResolver;
測(cè)試成功
以上就是Springboot文件上傳功能的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Springboot文件上傳的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot文件上傳的原理解析
- SpringBoot+ruoyi框架文件上傳和下載的實(shí)現(xiàn)
- tdesign的文件上傳功能實(shí)現(xiàn)(微信小程序+idea的springboot)
- SpringBoot中的文件上傳和異常處理詳解
- SpringBoot中的文件上傳與下載詳解
- SpringBoot文件上傳同時(shí)接收復(fù)雜參數(shù)的過程詳解
- SpringBoot實(shí)現(xiàn)項(xiàng)目文件上傳的方法詳解
- SpringBoot文件上傳與下載功能實(shí)現(xiàn)詳解
- SpringBoot簡單實(shí)現(xiàn)文件上傳
- SpringBoot整合Hutool實(shí)現(xiàn)文件上傳的使用示例
相關(guān)文章
SpringBoot文件上傳與下載功能實(shí)現(xiàn)詳解
文件上傳與下載是Web應(yīng)用開發(fā)中常用的功能之一。接下來我們將討論如何在Spring?Boot的Web應(yīng)用開發(fā)中,如何實(shí)現(xiàn)文件的上傳與下載,感興趣的可以了解一下2022-10-10Java生成和解析XML格式文件和字符串的實(shí)例代碼
這篇文章主要介紹了Java生成和解析XML格式文件和字符串的實(shí)例代碼,需要的朋友可以參考下2014-02-02Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12java判斷l(xiāng)ist不為空的實(shí)現(xiàn),和限制條數(shù)不要在一起寫
這篇文章主要介紹了java判斷l(xiāng)ist不為空的實(shí)現(xiàn),和限制條數(shù)不要在一起寫。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01Spring?Boot?Admin?添加報(bào)警提醒和登錄驗(yàn)證功能的具體實(shí)現(xiàn)
報(bào)警提醒功能是基于郵箱實(shí)現(xiàn)的,當(dāng)然也可以使用其他的提醒功能,如釘釘或飛書機(jī)器人提醒也是可以的,但郵箱報(bào)警功能的實(shí)現(xiàn)成本最低,所以本文我們就來看郵箱的報(bào)警提醒功能的具體實(shí)現(xiàn)2022-01-01