Spring中的Multipart請求處理

1.簡介

在本教程中,我們將重點介紹在Spring Boot中發送多部分請求的各種機制。多部分請求包括發送各種不同類型的數據,這些數據被邊界分隔為單個HTTP方法調用的一部分。

通常,我們可以在此請求中發送複雜的JSON,XML或CSV數據,以及傳輸多部分文件。多部分文件的示例可以是音頻或圖像文件。同樣,我們也可以將包含多部分文件的簡單鍵/值對數據作為多部分請求發送。

讓我們研究一下發送數據的各種方式。

2.使用@ModelAttribute

讓我們考慮一個簡單的用例,該用例使用表格發送由姓名和文件組成的員工數據。

首先,讓我們創建一個Employee抽象來存儲表單數據:

public class Employee {

 private String name;

 private MultipartFile document;

 }

接下來,讓我們使用Thymeleaf生成表單:

<form action="#" th:action="@{/employee}" th:object="${employee}" method="post" enctype="multipart/form-data">

 <p>name: <input type="text" th:field="*{name}" /></p>

 <p>document:<input type="file" th:field="*{document}" multiple="multiple"/>

 <input type="submit" value="upload" />

 <input type="reset" value="Reset" /></p>

 </form>

需要注意的重要一點是,我們在視圖enctype聲明為multipart/form-data

最後,我們將創建一個接受表單數據(包括多部分文件)的方法:

@RequestMapping(path = "/employee", method = POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })

 public String saveEmployee(@ModelAttribute Employee employee) {

 employeeService.save(employee);

 return "employee/success";

 }

這裡,兩個特別重要的細節是:

  • consumes屬性值設置為multipart/form-data
  • @ModelAttribute已將所有表單數據(包括上載的文件)捕獲到Employee

3.使用@RequestPart

該批註將multipart請求的一部分與method參數關聯,這對於將復雜的多屬性數據作為有效載荷(例如JSON或XML)發送很有用。

讓我們創建一個帶有兩個參數的方法,第一個參數為Employee類型,第二個MultipartFile為MultipartFile。此外,我們將使用@RequestPart註釋這兩個參數:

@RequestMapping(path = "/requestpart/employee", method = POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })

 public ResponseEntity<Object> saveEmployee(@RequestPart Employee employee, @RequestPart MultipartFile document) {

 employee.setDocument(document);

 employeeService.save(employee);

 return ResponseEntity.ok().build();

 }

現在,要查看該註解的實際效果,讓我們使用MockMultipartFile創建測試:

@Test

 public void givenEmployeeJsonAndMultipartFile_whenPostWithRequestPart_thenReturnsOK() throws Exception {

 MockMultipartFile employeeJson = new MockMultipartFile("employee", null,

 "application/json", "{\"name\": \"Emp Name\"}".getBytes());



 mockMvc.perform(multipart("/requestpart/employee")

 .file(A_FILE)

 .file(employeeJson))

 .andExpect(status().isOk());

 }

上面要注意的重要一點是,我們已將Employee部分application/JSON 。此外,除了分段文件之外,我們還將這些數據作為JSON文件發送。

有關如何測試多部分請求的更多詳細信息,請參見此處。

4.使用@RequestParam

發送多部分數據的另一種方法是使用@RequestParam 。這對於簡單數據特別有用,它與文件一起作為鍵/值對發送

@RequestMapping(path = "/requestparam/employee", method = POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })

 public ResponseEntity<Object> saveEmployee(@RequestParam String name, @RequestPart MultipartFile document) {

 Employee employee = new Employee(name, document);

 employeeService.save(employee);

 return ResponseEntity.ok().build();

 }

讓我們為此方法編寫測試以演示:

@Test

 public void givenRequestPartAndRequestParam_whenPost_thenReturns200OK() throws Exception {

 mockMvc.perform(multipart("/requestparam/employee")

 .file(A_FILE)

 .param("name", "testname"))

 .andExpect(status().isOk());

 }

5.結論

在本文中,我們研究瞭如何在Spring Boot中有效處理多部分請求。

最初,我們使用模型屬性發送多部分錶單數據。然後,我們研究瞭如何使用@RequestPart@RequestParam批註分別接收多部分數據。