您好,登錄后才能下訂單哦!
這篇文章主要介紹了Springboot文件上傳功能怎么實現的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Springboot文件上傳功能怎么實現文章都會有所收獲,下面我們一起來看看吧。
在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”。
效果圖如下:
在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已經自動配置了StandardServletMultipartResolver類來處理文件上傳請求,因此能夠直接在控制器方法中使用MultipartFile讀取文件信息。 @RequestParam中文件名稱屬性需要與前端頁面中input文件輸入框設置的name屬性一致。如果文件為空則返回上傳失敗,如果不為空則根據日期生成一個新的文件名,讀取文件流程并寫入指定的路徑中,最后返回上傳成功的提示信息。
需要注意的是文件上傳路徑的設置。在上述代碼中設置的文件保存路徑為D:\upload\,即在D盤下的upload文件夾。如果項目部署在Linux系統中的話,寫法與此不同。比如想要把文件上傳到/opt/newbee/upload目錄下,就需要把路徑設置的代碼改為private final static String FILE_UPLOAD_PATH = “/opt/newbee/upload/”。這一點需要注意,兩種系統的寫法存在一些差異。如果文件存儲目錄還沒有創建的話,首先需要創建該目錄,然后啟動項目進行文件上傳測試。
在編碼完成后,啟動Spring Boot項目。在啟動成功后,打開瀏覽器并輸入測試頁面地址:
http://localhost:8080/upload-test.html
打開后選擇上傳的文件,然后上傳,顯示成功。
檢查本機upload目錄下是否有改文件(注意這里需要在對應的位置建立好upload文件夾)
另外,在Spring Boot項目中支持單個文件的最大值默認為1MB,支持單個請求最大值默認10 MB。如果選擇了大于默認值的文件進行上傳,比如一個1.2MB的文件或者一個11MB的請求,就會報錯。
Spring Boot項目與普通Spring項目的目錄結構不同,并沒有webapp目錄,因此無法與普通的Java Web項目一樣,上傳文件到webapp目錄中并直接根據目錄進行訪問。Spring Boot項目中通常使用自定義靜態資源映射目錄,以此來實現文件上傳整個流程的閉環。比如在前文文件上傳案例中,在文件上傳到upload目錄后,會增加一個自定義靜態資源映射配置,使得在upload下的靜態資源可以通過該映射地址被訪問到。
新建config包并在config包中新增SpringBootWebMvcConfigurer類,實現代碼如下所示:
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/”開頭的靜態資源在請求時都會映射到D盤的upload目錄下。路徑的設置與前文中上傳文件的設置目錄類似,不同系統的文件路徑的寫法不同(比如Linux和Windows)。同時需要注意在設置靜態資源映射路徑時,路徑前需要添加“file:”前綴。
最后修改一下在文件上傳時的返回信息,把路徑拼裝好并返回到頁面上,以便于功能測試,UploadController代碼的修改如下所示:
return "上傳成功,地址為:/upload/"+newFileName;
最后啟動項目進行測試
檢查對應目錄下是否有文件
上傳成功完成。
首先,在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屬性統一命名為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 "參數錯誤"; } if (files.length>5){ return "文件最多上傳5個"; } String uploadResult = "上傳成功,地址為:<br>"; for (MultipartFile file:files){ String fileName = file.getOriginalFilename(); if (StringUtils.isEmpty(fileName)){ //表示無文件信息,跳出當前循環 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()方法相比,多文件上傳有兩處改動。
第一,文件參數在接收時的代碼改動。在多文件上傳并接收參數時使用的是@RequestPart注解,且接收的文件參數是一個數組MultipartFile。而單文件在上傳時使用的是@RequestParam注解,接收的文件是單個對象。
第二,文件在保存時增加循環邏輯。多文件保存的處理方式與單文件在上傳時比較類似,只是增加了循環邏輯,對接收的MultipartFile數組中每一個文件進行存儲操作,最后拼接文件的地址信息并返回。
另外一個需要注意的知識點,多文件上傳在接收參數時,參數名稱files需要完全對應input框中的name屬性。比如本次演示,在upload-same-file-name.html文件中所有文件輸入框的name屬性都是files;在后端處理時,uploadFilesBySameName()方法的參數名稱也定義為files,兩個名稱是對應的。如果所有文件輸入框的name屬性都改為uploadFiles,那么uploadFilesBySameName()方法的參數名稱也需要改為uploadFiles,否則接收的文件對象數組為空。
在編碼完成后,啟動Spring Boot項目。在在啟動成功后打開瀏覽器并輸入多圖上傳的測試頁面地址:
http://localhost:8080/upload-same-file-name.html
實際效果:
首先,在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)){ //表示無文件信息,跳出當前循環 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()方法相比,文件名不同時的改動只有一處,即文件參數在接收時的代碼做了改動。在讀取文件信息時的邏輯是自行實現的代碼邏輯,首先調用isMultipart()方法判斷當前請求是否為文件上傳請求,如果不是則不進行處理,如果是文件上傳請求,則HttpServletReques對象轉換為MultipartHttpServletRequest對象,并讀取文件數據,在讀取完成后再依次進行存儲。存儲文件的過程與之前的邏輯一致,最后拼接文件的地址信息并返回。
另外,需要判斷當前請求是否為文件上傳請求時要用到StandardServletMultipart Resolver類isMultipart()方法。前文中提到的StandardServletMultipartResolver類已經自動配置,所以可以直接在UploadController類中使用@Autowired注解注入,代碼如下所示:
@Autowired private StandardServletMultipartResolver standardServletMultipartResolver;
測試成功
關于“Springboot文件上傳功能怎么實現”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Springboot文件上傳功能怎么實現”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。