摘要:要使用容器上傳文件,您需要注冊一個類在中。最好不要使用內容加載應用程序的文件系統。允許用戶上傳文件的表單從后端提供的文件列表調整文件上傳限制配置文件上傳時,設置文件大小限制通常很有用。
本指南將指導您完成創建可以接收HTTP多文件上傳服務器應用程序的過程。
你要構建什么
您將創建一個接受文件上傳的Spring Boot Web應用程序。您還將構建一個簡單的HTML界面來上傳測試文件。
你需要什么
大約15分鐘
最喜歡的文本編輯器或IDE
JDK 1.8或更高版本
Gradle 4+或Maven 3.2+
您還可以將代碼直接導入IDE:
使用STS構建/導入入門指南
使用IntelliJ IDEA導入入門指南
如何完成本指南
與大多數Spring入門指南一樣,您可以從頭開始并完成每個步驟,或者您可以繞過您已熟悉的基本設置步驟。無論哪種方式,您最終都會使用工作代碼。
要從頭開始,請繼續使用Gradle構建。
要跳過基礎知識,請執行以下操作:
下載并解壓縮本指南的源存儲庫,或使用Git克隆它:
git clone https://github.com/spring-guides/gs-uploading-files.git
進入gs-uploading-files/initial
跳轉到創建Application類。
完成后,可以根據ggs-uploading-files/complete中的代碼檢查結果。
使用Gradle構建首先,設置一個基本的構建腳本。在使用Spring構建應用程序時,您可以使用任何您喜歡的構建系統,但此處包含了使用Gradle和Maven所需的代碼。如果您不熟悉這兩者,請參閱使用Gradle構建Java項目或使用Maven構建Java項目。
創建目錄結構
在您選擇的項目目錄中,創建以下子目錄結構;例如,在*nix系統上使用mkdir -p src/main/java/hello:
└── src └── main └── java └── hello
創建Gradle構建文件
下面是最初的Gradle構建文件。
buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE") } } apply plugin: "java" apply plugin: "eclipse" apply plugin: "org.springframework.boot" apply plugin: "io.spring.dependency-management" bootJar { baseName = "gs-uploading-files" version = "0.1.0" } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-thymeleaf") testCompile("org.springframework.boot:spring-boot-starter-test") }
在Spring Boot gradle plugin提供了許多便捷的功能:
它收集類路徑上的所有jar并構建一個可運行的“über-jar”,這使得執行和傳輸服務更加方便。
它搜索public static void main()標記為可運行類的方法。
它提供了一個內置的依賴項解析器,它設置版本號以匹配Spring Boot依賴項。您可以覆蓋任何您希望的版本,但它將默認為Boot的所選版本集。
使用Maven構建首先,設置一個基本的構建腳本。在使用Spring構建應用程序時,您可以使用任何您喜歡的構建系統,但此處包含了使用Maven所需的代碼。如果您不熟悉Maven,請參閱使用Maven構建Java項目。
創建目錄結構
在您選擇的項目目錄中,創建以下子目錄結構;例如,在*nix系統上使用mkdir -p src/main/java/hello:
└── src └── main └── java └── hello
pom.xml
4.0.0 org.springframework gs-uploading-files 0.1.0 org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
在Spring Boot gradle plugin提供了許多便捷的功能:
它收集類路徑上的所有jar并構建一個可運行的“über-jar”,這使得執行和傳輸服務更加方便。
它搜索public static void main()標記為可運行類的方法。
它提供了一個內置的依賴項解析器,它設置版本號以匹配Spring Boot依賴項。您可以覆蓋任何您希望的版本,但它將默認為Boot的所選版本集。
使用IDE構建閱讀如何將本指南直接導入使用STS構建/導入入門指南。
閱讀使用IntelliJ IDEA導入入門指南中如何使用本指南。
創建一個Application類
要啟動Spring Boot MVC應用程序,我們首先需要一個啟動器; spring-boot-starter-thymeleaf和spring-boot-starter-web已經添加為依賴關系。要使用Servlet容器上傳文件,您需要注冊一個MultipartConfigElement類(在web.xml中**)。感謝Spring Boot,一切都是自動配置的!
您開始使用此應用程序所需的只是以下Application類。
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
作為自動配置Spring MVC的一部分,Spring Boot將創建一個MultipartConfigElement bean并為文件上傳做好準備。
創建文件上傳控制器
初始應用程序已經包含一些類來處理在磁盤上存儲和加載上傳的文件; 它們都位于hello.storage包中。我們將在新的FileUploadController中使用它們。
src/main/java/hello/FileUploadController.java
package hello; 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 hello.storage.StorageFileNotFoundException; import hello.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().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(); } }
這個類帶有@Controller注解,因此Spring MVC可以選擇并查找路由。每個方法都標記有@GetMapping或@PostMapping將路徑和HTTP操作綁定到特定的Controller操作。
在這種情況下:
GET /查找從StorageService上傳的文件的當前列表,并將其加載到Thymeleaf模板中。它使用MvcUriComponentsBuilder計算到實際資源的鏈接
GET /files/{filename}加載資源(如果存在),并將其發送到瀏覽器以使用Content-Disposition響應頭進行下載
POST /適用于處理多部分消息file并將其提供給StorageService保存
在生產場景中,您更有可能將文件存儲在臨時位置,數據庫或Mongo的GridFS之類的NoSQL存儲中。最好不要使用內容加載應用程序的文件系統。
您需要為控制器提供與StorageService存儲層(例如文件系統)交互的控件。界面是這樣的:
src/main/java/hello/storage/StorageService.java
package hello.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(); }
示例應用程序中有一個接口的示例實現。如果您想節省時間,可以復制并粘貼它。
創建一個簡單的HTML模板
為了構建一些有趣的東西,下面的Thymeleaf模板是上傳文件以及顯示已上傳內容的一個很好的例子。
src/main/resources/templates/uploadForm.html
該模板有三個部分:
頂部的可選消息,其中Spring MVC寫入了一個flash范圍的消息。
允許用戶上傳文件的表單
從后端提供的文件列表
調整文件上傳限制
配置文件上傳時,設置文件大小限制通常很有用。想象一下嘗試處理5GB文件上傳!使用Spring Boot,我們可以MultipartConfigElement使用一些屬性設置調整其自動配置。
將以下屬性添加到現有屬性設置:
src/main/resources/application.properties
spring.servlet.multipart.max-file-size=128KB spring.servlet.multipart.max-request-size=128KB spring.http.multipart.enabled=false
多部分設置受限制如下:
spring.http.multipart.max-file-size 設置為128KB,意味著總文件大小不能超過128KB。
spring.http.multipart.max-request-size 設置為128KB,表示a的總請求大小multipart/form-data不能超過128KB。
構建可執行的JAR
雖然可以將此服務打包為傳統的WAR文件以部署到外部應用程序服務器,但下面演示的更簡單的方法創建了一個獨立的應用程序。您將所有內容打包在一個可執行的JAR文件中,由一個好的舊Java main()方法驅動。在此過程中,您使用Spring的支持將Tomcat servlet容器嵌入為HTTP運行時,而不是部署到外部實例。
您還需要一個目標文件夾來上傳文件,所以讓我們增強基本Application類并添加一個Boot CommandLineRunner,它在啟動時刪除并重新創建該文件夾:
src/main/java/hello/Application.java
package hello; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import hello.storage.StorageProperties; import hello.storage.StorageService; @SpringBootApplication @EnableConfigurationProperties(StorageProperties.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean CommandLineRunner init(StorageService storageService) { return (args) -> { storageService.deleteAll(); storageService.init(); }; } }
@SpringBootApplication 是一個便利注釋,添加了以下所有內容:
@Configuration 標記該類作為應用程序上下文的bean定義的源。
@EnableAutoConfiguration 告訴Spring Boot開始根據類路徑設置,其他bean和各種屬性設置添加bean。
通常你會添加@EnableWebMvc一個Spring MVC應用程序,但Spring Boot會在類路徑上看到spring-webmvc時自動添加它。這會將應用程序標記為Web應用程序并激活關鍵行為,例如設置DispatcherServlet。
@ComponentScan告訴Spring在包中尋找其他組件,配置和服務,允許它找到控制器。
main()方法使用Spring Boot的SpringApplication.run()方法來啟動應用程序。您是否注意到沒有一行XML?也沒有web.xml文件。此Web應用程序是100%純Java,您無需處理配置任何管道或基礎結構。
構建可執行的JAR
您可以使用Gradle或Maven從命令行運行該應用程序。或者,您可以構建一個包含所有必需依賴項,類和資源的可執行JAR文件,并運行該文件。這使得在整個開發生命周期中,跨不同環境等將服務作為應用程序發布,版本和部署變得容易。
如果您使用的是Gradle,則可以使用運行該應用程序./gradlew bootRun。或者您可以使用構建JAR文件./gradlew build。然后你可以運行JAR文件:
java -jar build/libs/gs-uploading-files-0.1.0.jar
如果您使用的是Maven,則可以使用該應用程序運行該應用程序./mvnw spring-boot:run。或者您可以使用構建JAR文件./mvnw clean package。然后你可以運行JAR文件:
java -jar target/gs-uploading-files-0.1.0.jar
上面的過程將創建一個可運行的JAR。您也可以選擇構建經典WAR文件。
它運行接收文件上傳的服務器端部分。顯示記錄輸出。該服務應在幾秒鐘內啟動并運行。
在服務器運行時,您需要打開瀏覽器并訪問http://localhost:8080/以查看上傳表單。選擇一個(小)文件并按“Upload”,您應該從控制器中看到成功頁面。選擇一個太大的文件,你會得到一個丑陋的錯誤頁面。
然后,您應該在瀏覽器窗口中看到類似的內容:
You successfully uploaded!
測試您的應用程序
在我們的應用程序中有多種方法可以測試此特定功能。這是一個利用MockMvc的示例,因此不需要啟動Servlet容器:
src/test/java/hello/FileUploadTests.java
package hello; import java.nio.file.Paths; import java.util.stream.Stream; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import hello.storage.StorageFileNotFoundException; import hello.storage.StorageService; @RunWith(SpringRunner.class) @AutoConfigureMockMvc @SpringBootTest public class FileUploadTests { @Autowired private MockMvc mvc; @MockBean private StorageService storageService; @Test public void shouldListAllFiles() throws Exception { given(this.storageService.loadAll()) .willReturn(Stream.of(Paths.get("first.txt"), Paths.get("second.txt"))); this.mvc.perform(get("/")).andExpect(status().isOk()) .andExpect(model().attribute("files", Matchers.contains("http://localhost/files/first.txt", "http://localhost/files/second.txt"))); } @Test public void shouldSaveUploadedFile() throws Exception { MockMultipartFile multipartFile = new MockMultipartFile("file", "test.txt", "text/plain", "Spring Framework".getBytes()); this.mvc.perform(fileUpload("/").file(multipartFile)) .andExpect(status().isFound()) .andExpect(header().string("Location", "/")); then(this.storageService).should().store(multipartFile); } @SuppressWarnings("unchecked") @Test public void should404WhenMissingFile() throws Exception { given(this.storageService.loadAsResource("test.txt")) .willThrow(StorageFileNotFoundException.class); this.mvc.perform(get("/files/test.txt")).andExpect(status().isNotFound()); } }
在那些測試中,我們使用各種模擬來設置與Controller的交互,以及StorageService使用Servlet容器本身的MockMultipartFile交互。
概要
恭喜!您剛剛編寫了一個使用Spring處理文件上傳的Web應用程序。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73185.html
摘要:依賴于對請求的支持。使用解析兼容的沒有構造器參數,也沒有要設置的參數,這樣,在應用上下文中,將其聲明為就會非常簡單。默認是沒有限制的整個請求的容量。 Spring MVC 高級的技術 本章內容: Spring MVC配置的替代方案 處理文件上傳 在控制器中處理異常 使用flash屬性 稍等還沒結束 說明 如果你有幸能看到。后面的章節暫時不更新了,改變學習方式了。重要理解思想,這本書...
摘要:實現協議實現文件斷點上傳關于協議提供一種基于和機制用于文件斷點續傳。請求請求當前文件的服務器信息,返回文件大小和當前進度。請求上傳文件,寫入磁盤系統。是最簡單的一個文件上傳頁面。參考文獻關于協議本文中用到的關于請求 Spring Boot實現TUS協議實現文件斷點上傳 關于Tus TUS協議提供一種基于 HTTP/1.1 和 HTTP/2 機制用于文件斷點續傳。 舉例 HEAD請求用來...
摘要:搭建圖片服務器本章內容通過和搭建圖片服務器。第二個部分是為了更好的體驗上傳,批量上傳,回顯功能的富文本編輯器。總結搭建服務器的思維實現上傳圖片的功能上傳圖片的功能源碼搭建圖片服務器到這里就結束了,有什么不足的地方,請賜教。 Nginx 搭建圖片服務器 本章內容通過Nginx 和 FTP 搭建圖片服務器。在學習本章內容前,請確保您的Linux 系統已經安裝了Nginx和Vsftpd。 N...
摘要:實踐案例包括兩個項目,服務提供者項目名,調用服務項目名,主要給出兩個服務之間的調用過程,文件上傳功能不提供項目框架依賴一文件上傳服務控制層文件上傳控制文件上傳文件上傳開始文件上傳結束,耗時文件上傳失敗業務層上傳文件判 實踐案例包括兩個項目,服務提供者項目名:upload-service,調用服務項目名:upload-client,主要給出兩個服務之間的調用過程,文件上傳功能不提供 項目...
摘要:的官方文檔中將調用的入口稱作,而在的示例代碼中將其命名為,其實指的是同一個東西。其次是類至此,一個文件上傳的服務端接口已經編寫完成。 前言 SpringBoot的官方文檔中關于Jersey的介紹并不是很全面: 27.3 JAX-RS and Jersey,SpringBoot-Sample項目里面也只有非常基礎的代碼,對于一些復雜的常用需求,這個文檔給不了任何幫助。 為了使用Jerse...
閱讀 780·2023-04-25 16:55
閱讀 2811·2021-10-11 10:59
閱讀 2077·2021-09-09 11:38
閱讀 1790·2021-09-03 10:40
閱讀 1490·2019-08-30 15:52
閱讀 1130·2019-08-30 15:52
閱讀 960·2019-08-29 15:33
閱讀 3499·2019-08-29 11:26