javascript
一篇文章教你学会使用SpringBoot实现文件上传和下载
文章目錄
- 一、搭建SpringBoot開發環境
- 1、創建項目
- 2、配置application.properties參數
- 3、實體響應類和異常信息類
- 4、創建FileController
- 二、接口測試
- 1、在完成上述的代碼之后運行程序,運行完成之后就可以使用Postman進行測試了。
- 2,測試下載文件
- 三、使用Web網頁上傳
寫在前面: 我是「境里婆娑」。我還是從前那個少年,沒有一絲絲改變,時間只不過是考驗,種在心中信念絲毫未減,眼前這個少年,還是最初那張臉,面前再多艱險不退卻。
寫博客的目的就是分享給大家一起學習交流,如果您對 Java感興趣,可以關注我,我們一起學習。
前言:上篇文章 一篇文章教你學會Java基礎I/O流 我們已經對I/O流有了一定了解,在這里中,您將學習如何使用Spring Boot實現Web服務中的文件上傳和下載功能。首先會構建一個REST API實現上傳及下載的功能,然后使用Postman工具來測試這些接口,最后創建一個Web界面,如果對SpringBoot不熟悉的話可以看這篇文章: springboot系列文章
導語本文主要講解:
一、搭建SpringBoot開發環境
1、創建項目
開發環境為Intellij IDEA,項目創建很簡單,按照以下的步驟創建即可:
- File -> New -> Project
- 選擇 Spring Initializr,點擊 Next
- 填寫 Group (項目域名) 和 Artifact (項目別名)
- 構建類型可以選擇 Maven
- 添加 Web 依賴
- 輸入項目名稱及保存路徑,完成創建
如果覺得上面看著不直觀,可以看下面的gif圖整個創建過程。
項目創建完畢就可以開發,項目的整體結構如下所示:
2、配置application.properties參數
項目創建完成之后,需要在application.properties中添加以下參數:
server.port=8080 ## MULTIPART (MultipartProperties) # 開啟 multipart 上傳功能 spring.servlet.multipart.enabled=true # 文件寫入磁盤的閾值 spring.servlet.multipart.file-size-threshold=2KB # 最大文件大小 spring.servlet.multipart.max-file-size=200MB # 最大請求大小 spring.servlet.multipart.max-request-size=215MB # 文件存儲所需參數 # 所有通過 REST API 上傳的文件都將存儲在此目錄下 file.upload.path=D:/aplus其中file.upload.path =D:/aplus參數為自定義的參數,有兩種方式可以獲取到此參數
- 使用@Value("${file.upload.path}")
- 使配置參數可以自動綁定到POJO類。
使配置參數綁定實體類詳細代碼如下:
/*** @author zhaosl* @ProjectName springboot-upload* @date 2020/6/3 23:51*/ @ConfigurationProperties(prefix = "file") public class FileProperty {private String filePath;public String getFilePath() {return filePath;}public void setFilePath(String filePath) {this.filePath = filePath;} }敲黑板這是重點如果想要此配置性能必須在@SpringbootUploadApplication注解的類中添加@EnableConfigurationProperties注解以開啟ConfigurationProperties功能。
SpringbootUploadApplication啟動類
@SpringBootApplication @EnableConfigurationProperties({FileProperty.class }) public class SpringbootUploadApplication {public static void main(String[] args) {SpringApplication.run(SpringbootUploadApplication.class, args);}}3、實體響應類和異常信息類
文件成功后需要有的響應實體類UploadFileResponse和文件出現上傳異常類FileException來處理異常信息
響應實體類UploadFileResponse
/*** @author zhaosl* @ProjectName springboot-upload* @date 2020/6/3 23:58*/ public class UploadFileResponse {private String fileName;private String fileDownloadUri;private String fileType;private long size;public UploadFileResponse() {}public UploadFileResponse(String fileName, String fileDownloadUri, String fileType, long size) {this.fileName = fileName;this.fileDownloadUri = fileDownloadUri;this.fileType = fileType;this.size = size;}//get set 省略異常信息類FileException
/*** @author zhaosl* @ProjectName springboot-upload* @date 2020/6/4 0:04*/ public class FileException extends RuntimeException {public FileException(String message) {super(message);}public FileException(String message, Throwable cause) {super(message, cause);} }4、創建FileController
創建文件上傳下載所需的REST API接口
/*** @author shuliangzhao* @ProjectName springboot-upload* @date 2020/6/3 23:34*/ @RestController public class FileController {private static final Logger logger = LoggerFactory.getLogger(FileController.class);@Autowiredprivate FileService fileService;@PostMapping("/uploadFile")public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file){String fileName = fileService.storeFile(file);String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath().path("/downloadFile/").path(fileName).toUriString();return new UploadFileResponse(fileName, fileDownloadUri,file.getContentType(), file.getSize());}@PostMapping("/uploadMultipleFiles")public List<UploadFileResponse> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {List<UploadFileResponse> list = new ArrayList<>();if (files != null) {for (MultipartFile multipartFile:files) {UploadFileResponse uploadFileResponse = uploadFile(multipartFile);list.add(uploadFileResponse);}}return list;//簡單寫法/* return Arrays.stream(files).map(this::uploadFile).collect(Collectors.toList());*/}@GetMapping("/downloadFile/{fileName:.*}")public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request) {Resource resource = fileService.loadFileAsResource(fileName);String contentType = null;try {request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());} catch (IOException e) {logger.info("Could not determine file type.");}if(contentType == null) {contentType = "application/octet-stream";}return ResponseEntity.ok().contentType(MediaType.parseMediaType(contentType)).header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"").body(resource);}}FileController類收到請求后,調用FileService類的storeFile()方法將文件寫入到系統中進行存儲,其存儲目錄就是之前在application.properties配置文件中的file.upload.path參數的值。
下載接口downloadFile()在收到用戶請求之后,使用FileService類提供的loadFileAsResource()方法獲取存儲在系統中文件并返回文件供用戶下載。
FileService實現類為:
/*** @author shuliangzhao* @ProjectName springboot-upload* @date 2020/6/3 23:34*/ @Component public class FileService {private Path fileStorageLocation; // 文件在本地存儲的地址public FileService( @Value("${file.upload.path}") String path) {this.fileStorageLocation = Paths.get(path).toAbsolutePath().normalize();try {Files.createDirectories(this.fileStorageLocation);} catch (IOException e) {throw new FileException("Could not create the directory", e);}}/*** 存儲文件到系統* @param file 文件* @return 文件名*/public String storeFile(MultipartFile file) {// Normalize file nameString fileName = StringUtils.cleanPath(file.getOriginalFilename());try {// Check if the file's name contains invalid charactersif(fileName.contains("..")) {throw new FileException("Sorry! Filename contains invalid path sequence " + fileName);}// Copy file to the target location (Replacing existing file with the same name)Path targetLocation = this.fileStorageLocation.resolve(fileName);Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);return fileName;} catch (IOException ex) {throw new FileException("Could not store file " + fileName + ". Please try again!", ex);}}public Resource loadFileAsResource(String fileName) {try {Path filePath = this.fileStorageLocation.resolve(fileName).normalize();Resource resource = new UrlResource(filePath.toUri());if(resource.exists()) {return resource;} else {throw new FileException("File not found " + fileName);}} catch (MalformedURLException ex) {throw new FileException("File not found " + fileName, ex);}} }二、接口測試
1、在完成上述的代碼之后運行程序,運行完成之后就可以使用Postman進行測試了。
單個文件上傳調用接口為:http://localhost:8080/uploadFile
gif圖如下所示:
返回結果為:
多個文件上傳調用接口為:http://localhost:8080/uploadMultipleFiles
gif圖如下所示:
返回結果為:
[{"fileName": "8~}1OC59ZKA0)`[PI_NU[QK.png","fileDownloadUri": "http://localhost:8080/downloadFile/8~%7D1OC59ZKA0)%60%5BPI_NU%5BQK.png","fileType": "image/png","size": 1525371},{"fileName": "1519897877-LNgupqGBki.jpg","fileDownloadUri": "http://localhost:8080/downloadFile/1519897877-LNgupqGBki.jpg","fileType": "image/jpeg","size": 25294} ]2,測試下載文件
在瀏覽器中輸入網址:http://localhost:8080/downloadFile/1519897877-LNgupqGBki.jpg
會把文件下載下來如下所示:
三、使用Web網頁上傳
增加thymeleaf前端解析器依賴,使SpringBoot工程可以訪問html網頁
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>** thymeleaf視圖解析器配置增加到配置文件中**
#在構建URL時添加到視圖名稱前的前綴(默認值:classpath:/templates/) spring.thymeleaf.prefix=classpath:/templates/ # 在構建URL時附加到視圖名稱的后綴。 spring.thymeleaf.suffix=.html新建的index.html網頁
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>文件上傳</title> </head> <body> <form method="post" action="/uploadFile" enctype="multipart/form-data"><input type="file" name="file"><br><br><input type="submit" value="提交"> </form> </body> </html>增加訪問的index.html網頁控制器
/*** @author shuliangzhao* @ProjectName springboot-upload* @date 2020/6/4 23:29*/ @Controller public class IndexController {@GetMapping("/")public String index() {return "index";} }啟動項目訪問首頁開始上傳文件如下所示:
到此文件的上傳及下載功能已完成。在正式環境中可能還需要將上傳的文件路徑保存到數據庫,到時候可以根據需要做處理。
本文來源代碼: https://github.com/FadeHub/springboot-upload
—————————————————————————————————
由于本人水平有限,難免有不足,懇請各位大佬不吝賜教!
總結
以上是生活随笔為你收集整理的一篇文章教你学会使用SpringBoot实现文件上传和下载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一篇文章教你学会Java基础I/O流
- 下一篇: 一篇文章教你学会使用SpringBatc