21.10.4 处理表单中的文件上传

当解析器MultipartResolver完成处理时,请求便会像其他请求一样被正常流程处理。首先,创建一个接受文件上传的表单将允许用于直接上传整个表单。编码属性(enctype="multipart/form-data")能让浏览器知道如何对多路上传请求的表单进行编码(encode)。

  1. <html>
  2. <head>
  3. <title>Upload a file please</title>
  4. </head>
  5. <body>
  6. <h1>Please upload a file</h1>
  7. <form method="post" action="/form" enctype="multipart/form-data">
  8. <input type="text" name="name"/>
  9. <input type="file" name="file"/>
  10. <input type="submit"/>
  11. </form>
  12. </body>
  13. </html>

下一步是创建一个能处理文件上传的控制器。这里需要的控制器与一般注解了@Controller的控制器基本一样,除了它接受的方法参数类型是MultipartHttpServletRequest,或MultipartFile

  1. @Controller
  2. public class FileUploadController {
  3. @RequestMapping(path = "/form", method = RequestMethod.POST)
  4. public String handleFormUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) {
  5. if (!file.isEmpty()) {
  6. byte[] bytes = file.getBytes();
  7. // store the bytes somewhere
  8. return "redirect:uploadSuccess";
  9. }
  10. return "redirect:uploadFailure";
  11. }
  12. }

请留意@RequestParam注解是如何将方法参数对应到表单中的定义的输入字段的。在上面的例子中,我们拿到了byte[]文件数据,只是没对它做任何事。在实际应用中,你可能会将它保存到数据库、存储在文件系统上,或做其他的处理。

当使用Servlet 3.0的多路传输转换时,你也可以使用javax.servlet.http.Part作为方法参数:

  1. @Controller
  2. public class FileUploadController {
  3. @RequestMapping(path = "/form", method = RequestMethod.POST)
  4. public String handleFormUpload(@RequestParam("name") String name, @RequestParam("file") Part file) {
  5. InputStream inputStream = file.getInputStream();
  6. // store bytes from uploaded file somewhere
  7. return "redirect:uploadSuccess";
  8. }
  9. }