繁体   English   中英

Spring 启动 MultipartFile 方法

[英]Spring boot MultipartFile methods

在 Spring Boot 中,我们使用MultipartFile将文件从客户端发送到服务器。 以下是如何使用它的示例:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String uploadFile(@RequestParam("file") MultipartFile uploadfile) {
    System.out.println("Name: " + uploadfile.getName());
    System.out.println("");
    return "Done";
}

我知道MultipartFile是一个接口,它使得它的所有成员(即getName )抽象。 我不明白的是,我应该如何使用这个接口而不自己创建一个实现?

如果您查看 Spring 源代码,您会发现CommonsMultipartFile ,它实现了诸如getName()

当您声明要接收MultipartFile ,您实际上并不关心它是如何在幕后实现的。 你只关心文件。 Spring Framework 将决定为您提供哪种实现。

另一个有趣的实现是MockMultipartFile ,它可以在测试期间使用。 同样,由于它实现了相同的接口,因此您无需以任何方式更改您的方法。

由于它是一个接口,因此需要有人提供实现。 在这种情况下,Spring 在运行时提供它。

Spring MVC 如何处理文件上传在 Spring 参考指南的相关部分进行了解释。

当一个请求首先到达DispatcherServlet ,它会检测到它是一个多部分请求,并将请求处理委托给配置的MultipartResolver (这也是一个接口)。 DispatcherServlet通过一个众所周知的名称multipartResolver (这是在DispatcherServlet硬编码的)来检测这个MultipartResolver

这个MultipartResolver实例的作用是将实际的HttpServletRequest包装成MultipartServletRequest (这是HttpServletRequest的 Spring MVC 扩展HttpServletRequest) and this wrapper knowns how to handle the incoming request and create the appropriate MultipartFile` 实现。

Spring 有 3 种风格的这个接口

  1. CommonsMultipartResolver使用Apache Commons FileUpload
  2. StandardServletMultipartResolver使用 Servlet 3.0 标准 Servlet API 文件上传
  3. 用于单元测试的MockMultipartFile

当使用 Spring Boot 处理文件上传时,它默认配置第二个选项StandardServletMultipartResolver

现在,当多部分请求的复杂处理完成时, DispatcherServlet将请求传递给选定的处理程序(即您的控制器)。 RequestMappingHandlerAdapter检查选定的请求处理方法并将填充所有方法参数。

最后是RequestParamMethodArgumentResolver将实际值绑定到MultipartFile对象。 MultipartServletRequest上使用getFiles方法。 对于默认的 Spring Boot 配置实现( StandardMultipartHttpServletRequest ),这将提供StandardMultipartFile实例,它是上述StandardMultipartHttpServletRequest的嵌入类

能够使用MultipartFile接口的优点是您可以更改为CommonsMultipartResolver而无需更改您的控制器。

Spring 有一些实现MultipartFile接口的类。 例如,有CommonsMultipartFile类: http : CommonsMultipartFile

当一个 multipart 表单被提交到你的控制器时,Spring 会解析这个表单,构建一些实现MultipartFile的类的对象(可能是CommonsMultipartFile )并使用这个对象作为参数调用你的控制器方法。

所以你不需要实现MultipartFile方法,它们已经被 Spring 实现了。

var factory = new DiskFileItemFactory()
var fileItem = factory.createItem(
        "file",
        MediaType.APPLICATION_OCTET_STREAM_VALUE,
        true,
        "file"
)

try {
    fileItem.outputStream.use { outputStream ->
        // Copy your data into the outputStream
    }

    var multipartFile = new CommonsMultipartFile(fileItem)
} finally {
    fileItem.delete()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM