Multipart
在 啟用 MultipartResolver
之後,具有 multipart/form-data
的 POST 請求內容會被剖析,並可作為一般請求參數存取。下列範例存取一個一般表單欄位和一個上傳的檔案
-
Java
-
Kotlin
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
@Controller
class FileUploadController {
@PostMapping("/form")
fun handleFormUpload(@RequestParam("name") name: String,
@RequestParam("file") file: MultipartFile): String {
if (!file.isEmpty) {
val bytes = file.bytes
// store the bytes somewhere
return "redirect:uploadSuccess"
}
return "redirect:uploadFailure"
}
}
將引數型別宣告為 List<MultipartFile>
允許解析相同參數名稱的多個檔案。
當 @RequestParam
註解宣告為 Map<String, MultipartFile>
或 MultiValueMap<String, MultipartFile>
時,如果註解中未指定參數名稱,則 Map 會填入每個給定參數名稱的 multipart 檔案。
使用 Servlet multipart 剖析時,您也可以宣告 jakarta.servlet.http.Part 而不是 Spring 的 MultipartFile ,作為方法引數或集合值型別。 |
您也可以使用 multipart 內容作為資料繫結到 命令物件 的一部分。例如,前一個範例中的表單欄位和檔案可以是表單物件上的欄位,如下列範例所示
-
Java
-
Kotlin
class MyForm {
private String name;
private MultipartFile file;
// ...
}
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(MyForm form, BindingResult errors) {
if (!form.getFile().isEmpty()) {
byte[] bytes = form.getFile().getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
class MyForm(val name: String, val file: MultipartFile, ...)
@Controller
class FileUploadController {
@PostMapping("/form")
fun handleFormUpload(form: MyForm, errors: BindingResult): String {
if (!form.file.isEmpty) {
val bytes = form.file.bytes
// store the bytes somewhere
return "redirect:uploadSuccess"
}
return "redirect:uploadFailure"
}
}
Multipart 請求也可以從 RESTful 服務情境中的非瀏覽器用戶端提交。下列範例顯示具有 JSON 的檔案
POST /someUrl Content-Type: multipart/mixed --edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp Content-Disposition: form-data; name="meta-data" Content-Type: application/json; charset=UTF-8 Content-Transfer-Encoding: 8bit { "name": "value" } --edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp Content-Disposition: form-data; name="file-data"; filename="file.properties" Content-Type: text/xml Content-Transfer-Encoding: 8bit ... File Data ...
您可以使用 @RequestParam
作為 String
來存取「meta-data」部分,但您可能希望從 JSON 還原序列化它(類似於 @RequestBody
)。使用 @RequestPart
註解,在使用 HttpMessageConverter 轉換 multipart 後存取它
-
Java
-
Kotlin
@PostMapping("/")
public String handle(@RequestPart("meta-data") MetaData metadata,
@RequestPart("file-data") MultipartFile file) {
// ...
}
@PostMapping("/")
fun handle(@RequestPart("meta-data") metadata: MetaData,
@RequestPart("file-data") file: MultipartFile): String {
// ...
}
您可以將 @RequestPart
與 jakarta.validation.Valid
結合使用,或使用 Spring 的 @Validated
註解,這兩者都會導致套用標準 Bean 驗證。預設情況下,驗證錯誤會導致 MethodArgumentNotValidException
,此異常會轉換為 400 (BAD_REQUEST) 回應。或者,您可以透過 Errors
或 BindingResult
引數在控制器本機處理驗證錯誤,如下列範例所示
-
Java
-
Kotlin
@PostMapping("/")
public String handle(@Valid @RequestPart("meta-data") MetaData metadata, Errors errors) {
// ...
}
@PostMapping("/")
fun handle(@Valid @RequestPart("meta-data") metadata: MetaData, errors: Errors): String {
// ...
}
如果方法驗證適用,因為其他參數具有 @Constraint
註解,則會改為引發 HandlerMethodValidationException
。如需更多詳細資訊,請參閱關於 驗證 的章節。