搞定Multipart
Multipart解決了在一個HTTP請求里存放多種數據的問題,使得在一個HTTP請求里同時傳輸JSON和二進制數據成為可能,因此multipart大量應用在表單中。本文嘗試用最簡單的方式講解在AJAX時代的multipart實踐。
HTTP請求
Multipart有幾個重要的點:
- 請求的Content-Type必須為multipart/form-data,后面必須跟用於區分各個part的boundary
- 每個part以boundary開始,后面跟Content-Disposition:form-data以及part的name,以及可選的filename
- 每個part有可選的Content-Type
前端
前端可以使用FormData來表示multipart
var formData = new FormData();
formData.append("username", "Groucho");
formData.append("accountnum", 123456); // number 123456 is immediately converted to a string "123456"
// HTML file input, chosen by user
formData.append("userfile", fileInputElement.files[0]);
// JavaScript file-like object
var content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var blob = new Blob([content], { type: "text/xml"});
formData.append("webmasterfile", blob);
var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);
后端
以應用最廣泛的的Spring Boot為例。
-
可以使用
@RequestParam或者@RequestPart來標記multipart中的part,兩者的區別是,當參數類型不是String或者Multipart時,@RequestParam使用Converter或者PropertyEditor進行轉換,而@RequestPart使用HttpMessageConverters進行轉換。HTTPMessageConverters依賴Content-Type來選擇converter,同時@RequestBody也使用HTTPMessageConverters。因此,如果參數是key=value形式的,選擇@RequestParam,如果參數是JSON或者XML,選擇@RequestPart -
由於
HTTPMessageConverters依賴Content-Type,因此對於非String/MultipartFile/Part類型的參數,必須在請求中指定Content-Type,前端指定Content-Type的方法見代碼示例 -
由於自己實現
Converter或者PropertyEditor也是有一定代碼量的,而且現在都用JSON傳輸數據,所以更推薦使用@RequestPart
PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!

