Multipart

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

  • Java

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

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

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

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

  • Java

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

多部分请求也可以从非浏览器客户端在 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 转换后访问多部分:

  • Java

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

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

  • Java

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

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