跳到主要内容

多部分

ChatGPT-4o-mini 中英对照 Multipart

在启用 MultipartResolver 之后,multipart/form-data 的 POST 请求内容会被解析,并作为常规请求参数进行访问。以下示例访问一个常规表单字段和一个上传的文件:

@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";
}
}
java

将参数类型声明为 List<MultipartFile> 允许为同一参数名称解析多个文件。

@RequestParam 注解被声明为 Map<String, MultipartFile>MultiValueMap<String, MultipartFile> 时,如果在注解中没有指定参数名称,则该映射将根据每个给定的参数名称填充多部分文件。

备注

使用 Servlet 多部分解析时,您也可以声明 jakarta.servlet.http.Part 作为方法参数或集合值类型,而不是 Spring 的 MultipartFile

您还可以使用多部分内容作为数据绑定的一部分,绑定到一个 command object。例如,前面示例中的表单字段和文件可以是表单对象上的字段,如下例所示:

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";
}
}
java

在 RESTful 服务场景中,Multipart 请求也可以从非浏览器客户端提交。以下示例展示了一个包含 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 ...

您可以通过 @RequestParamString 的形式访问 "meta-data" 部分,但您可能希望将其从 JSON 反序列化(类似于 @RequestBody)。使用 @RequestPart 注解在通过 HttpMessageConverter 转换后访问多部分内容:

@PostMapping("/")
public String handle(@RequestPart("meta-data") MetaData metadata,
@RequestPart("file-data") MultipartFile file) {
// ...
}
java

您可以将 @RequestPartjakarta.validation.Valid 结合使用,或者使用 Spring 的 @Validated 注解,这两者都会导致标准 Bean 验证被应用。默认情况下,验证错误会导致 MethodArgumentNotValidException,这会转化为 400 (BAD_REQUEST) 响应。或者,您可以通过 ErrorsBindingResult 参数在控制器内本地处理验证错误,如以下示例所示:

@PostMapping("/")
public String handle(@Valid @RequestPart("meta-data") MetaData metadata, Errors errors) {
// ...
}
java

如果方法验证适用,因为其他参数具有 @Constraint 注解,则会引发 HandlerMethodValidationException。有关更多详细信息,请参见 验证 部分。