Spring認(rèn)證指南:了解如何構(gòu)建一個多文件上傳的 Spring 應(yīng)用程序
本攻略將引導(dǎo)您完結(jié)創(chuàng)立能夠接納 HTTP 多部分文件上傳的服務(wù)器應(yīng)用程序的進(jìn)程。
你將制作什么
您將創(chuàng)立一個承受文件上傳的 Spring Boot Web 應(yīng)用程序。您還將構(gòu)建一個簡單的 HTML 界面來上傳測驗(yàn)文件。
你需求什么
- 約15分鐘
- 最喜歡的文本編輯器或 IDE
- JDK 1.8或更高版本
- Gradle 4+或Maven 3.2+
- 您還能夠?qū)⒋a直接導(dǎo)入 IDE:彈簧工具套件 (STS)IntelliJ IDEA
怎么完結(jié)本攻略
像大多數(shù) Spring入門攻略一樣,您能夠從頭開端并完結(jié)每個進(jìn)程,也能夠繞過您現(xiàn)已了解的基本設(shè)置進(jìn)程。不管哪種辦法,您終究都會得到作業(yè)代碼。
要從頭開端,請持續(xù)從 Spring Initializr 開端。
要越過基礎(chǔ)知識,請履行以下操作:
- 下載并解壓本攻略的源代碼庫,或運(yùn)用Git克隆它:git clone https://github.com/spring-guides/gs-uploading-files.git
- 光盤進(jìn)入gs-uploading-files/initial
- 持續(xù)創(chuàng)立應(yīng)用程序類。
完結(jié)后,您能夠?qū)φ罩械拇a檢查成果
gs-uploading-files/complete。
從 Spring Initializr 開端
您能夠運(yùn)用這個預(yù)先初始化的項(xiàng)目并單擊 Generate 下載 ZIP 文件。此項(xiàng)目裝備為適合本教程中的示例。
手動初始化項(xiàng)目:
- 導(dǎo)航到https://start.spring.io。該服務(wù)提取應(yīng)用程序所需的一切依靠項(xiàng),并為您完結(jié)大部分設(shè)置。
- 挑選 Gradle 或 Maven 以及您要運(yùn)用的言語。本攻略假定您挑選了 Java。
- 單擊Dependencies并挑選Spring Web和Thymeleaf。
- 單擊生成。
- 下載生成的 ZIP 文件,該文件是依據(jù)您的挑選裝備的 Web 應(yīng)用程序的存檔。
假如您的 IDE 具有 Spring Initializr 集成,您能夠從您的 IDE 完結(jié)此進(jìn)程。
你也能夠從 Github 上 fork 項(xiàng)目并在你的 IDE 或其他編輯器中翻開它。
創(chuàng)立應(yīng)用程序類
要發(fā)動 Spring Boot MVC 應(yīng)用程序,首要需求一個發(fā)動器。在此示例中,
spring-boot-starter-thymeleaf并且spring-boot-starter-web已作為依靠項(xiàng)增加。要運(yùn)用 Servlet 容器上傳文件,您需求注冊一個MultipartConfigElement類(在 web.xml 中)。感謝 Spring Boot,一切都是為您主動裝備的!
開端運(yùn)用此應(yīng)用程序所需的只是以下UploadingFilesApplication類(來自
src/main/java/com/example/uploadingfiles/UploadingFilesApplication.java):
package com.example.uploadingfiles; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class UploadingFilesApplication { public static void main(String[] args) { SpringApplication.run(UploadingFilesApplication.class, args); } }
作為主動裝備 Spring MVC 的一部分,Spring Boot 將創(chuàng)立一個MultipartConfigElementbean 并為文件上傳做好準(zhǔn)備。
創(chuàng)立文件上傳控制器
初始應(yīng)用程序現(xiàn)已包括一些類來處理在磁盤上存儲和加載上傳的文件。它們都坐落
com.example.uploadingfiles.storage包裝中。您將在新的FileUploadController. 以下清單(來自
src/main/java/com/example/uploadingfiles/FileUploadController.java)顯現(xiàn)了文件上傳控制器:
package com.example.uploadingfiles; import java.io.IOException; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import com.example.uploadingfiles.storage.StorageFileNotFoundException; import com.example.uploadingfiles.storage.StorageService; @Controller public class FileUploadController { private final StorageService storageService; @Autowired public FileUploadController(StorageService storageService) { this.storageService = storageService; } @GetMapping("/") public String listUploadedFiles(Model model) throws IOException { model.addAttribute("files", storageService.loadAll().map( path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString()).build().toUri().toString()) .collect(Collectors.toList())); return "uploadForm"; } @GetMapping("/files/{filename:.+}") @ResponseBody public ResponseEntityserveFile(@PathVariable String filename) { Resource file = storageService.loadAsResource(filename); return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file); } @PostMapping("/") public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { storageService.store(file); redirectAttributes.addFlashAttribute("message", "You successfully uploaded " + file.getOriginalFilename() + "!"); return "redirect:/"; } @ExceptionHandler(StorageFileNotFoundException.class) public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) { return ResponseEntity.notFound().build(); } }
該類FileUploadController帶有注釋,@Controller以便 Spring MVC 能夠拾取它并查找路由。每個辦法都被標(biāo)記@GetMapping或@PostMapping將途徑和 HTTP 操作綁定到特定的控制器操作。
在這種情況下:
- GET /:從 中查找當(dāng)前上傳文件的列表StorageService并將其加載到 Thymeleaf 模板中。它經(jīng)過運(yùn)用 計算到實(shí)際資源的鏈接MvcUriComponentsBuilder。
- GET /files/{filename}:加載資源(假如存在)并運(yùn)用Content-Disposition呼應(yīng)頭將其發(fā)送到瀏覽器進(jìn)行下載。
- POST /:處理多部分音訊file并將其供給給StorageService保存。
在出產(chǎn)場景中,您更有可能將文件存儲在暫時位置、數(shù)據(jù)庫或 NoSQL 存儲(例如Mongo 的 GridFS)中。最好不要在應(yīng)用程序的文件體系中加載內(nèi)容。
您將需求供給一個StorageService以便控制器能夠與存儲層(例如文件體系)進(jìn)行交互。以下清單(來自
src/main/java/com/example/uploadingfiles/storage/StorageService.java)顯現(xiàn)了該界面:
package com.example.uploadingfiles.storage; import org.springframework.core.io.Resource; import org.springframework.web.multipart.MultipartFile; import java.nio.file.Path; import java.util.stream.Stream; public interface StorageService { void init(); void store(MultipartFile file); StreamloadAll(); Path load(String filename); Resource loadAsResource(String filename); void deleteAll(); }
創(chuàng)立 HTML 模板
以下 Thymeleaf 模板(來自
src/main/resources/templates/uploadForm.html)顯現(xiàn)了怎么上傳文件并顯現(xiàn)已上傳內(nèi)容的示例:
調(diào)整文件上傳限制
將以下特點(diǎn)增加到現(xiàn)有特點(diǎn)設(shè)置(在 中
src/main/resources/application.properties):
- spring.servlet.multipart.max-file-size 設(shè)置為 128KB,這意味著總文件巨細(xì)不能超過 128KB。
- spring.servlet.multipart.max-request-size設(shè)置為 128KB,這意味著 a 的總懇求巨細(xì)multipart/form-data不能超過 128KB。
運(yùn)轉(zhuǎn)應(yīng)用程序
@SpringBootApplication是一個方便的注釋,它增加了以下一切內(nèi)容:
- @Configuration: 將類標(biāo)記為應(yīng)用程序上下文的 bean 界說源。
- @EnableAutoConfiguration:告訴 Spring Boot 依據(jù)類途徑設(shè)置、其他 bean 和各種特點(diǎn)設(shè)置開端增加 bean。例如,假如spring-webmvc坐落類途徑上,則此注釋將應(yīng)用程序標(biāo)記為 Web 應(yīng)用程序并激活關(guān)鍵行為,例如設(shè)置DispatcherServlet.
- @ComponentScan: 告訴 Spring 在包中查找其他組件、裝備和服務(wù)com/example,讓它找到控制器。
構(gòu)建一個可履行的 JAR
此處描繪的進(jìn)程創(chuàng)立了一個可運(yùn)轉(zhuǎn)的 JAR。您還能夠構(gòu)建經(jīng)典的 WAR 文件。
它運(yùn)轉(zhuǎn)接納文件上傳的服務(wù)器端部分。顯現(xiàn)記錄輸出。該服務(wù)應(yīng)在幾秒鐘內(nèi)發(fā)動并運(yùn)轉(zhuǎn)。
然后,您應(yīng)該會在瀏覽器窗口中看到類似于以下內(nèi)容的行:
測驗(yàn)?zāi)膽?yīng)用程序
在這些測驗(yàn)中,您運(yùn)用各種模擬來設(shè)置與您的控制器以及StorageService與 Servlet 容器本身的交互,運(yùn)用MockMultipartFile.
有關(guān)集成測驗(yàn)的示例,請參見
FileUploadIntegrationTests類(坐落 中
src/test/java/com/example/uploadingfiles)。