我的问题很简单,但我真的不明白它是如何运作的。在sprin启动中,我们使用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这样的所有方法都是abstrack,我怎么能够使用这些方法而不会过度使用它们?
答案 0 :(得分:2)
如果您查看Spring源代码,您会找到CommonsMultipartFile
,它会实现getName()
等方法
当您声明要收到MultipartFile
时,您实际上并不关心它是如何在幕后实施的。你只关心这个文件。 Spring Framework将决定为您提供哪种实现。
其他有趣的实现是MockMultipartFile
,可以在测试期间使用。同样,由于它实现了相同的界面,因此您无需以任何方式更改方法。
由于它是一个界面,有人需要提供实现。在这种情况下,Spring在运行时提供它。
答案 1 :(得分:1)
Spring MVC如何处理文件上传在Spring参考指南的relevant section中进行了解释。
当请求进入时,它首先到达DispatcherServlet
,它将检测到它是一个多部分请求,并且该委托将请求处理到已配置的MultipartResolver
(这也是一个接口)。 DispatcherServlet
通过众所周知的名称MultipartResolver
检测到此multipartResolver
(这是DispatcherServlet
中的硬编码)。
这个MultipartResolver
实例做的是将实际的HttpServletRequest
包装到MultipartServletRequest
(这是HttpServletRequest) and this wrapper knowns how to handle the incoming request and create the appropriate
MultipartFile`实现的Spring MVC扩展。
Spring有这种界面的3种风格
CommonsMultipartResolver
使用Apache Commons FileUpload StandardServletMultipartResolver
使用Servlet 3.0标准Servlet API文件上传MockMultipartFile
进行单元测试默认情况下使用Spring Boot handle file uploads configures StandardMultipartHttpServletRequest
第二个选项StandardServletMultipartResolver
。
现在,当完成多部分请求的复杂处理时,DispatcherServlet
将请求传递给选定的处理程序(即您的控制器)。 RequestMappingHandlerAdapter
检查选定的请求处理方法,并填写所有方法参数。
最后,RequestParamMethodArgumentResolver
将实际值绑定到MultipartFile
对象。在getFiles
上使用MultipartServletRequest
方法。对于默认的Spring Boot配置实现(StandardMultipartFile
),这将给出{{3}}的实例,这是StandardMultipartHttpServletRequest
能够使用MultipartFile
界面的优势在于您无需更改控制器即可更改为CommonsMultipartResolver
。
答案 2 :(得分:0)
Spring有一些实现1
2
a
b
c
d
接口的类。例如,有MultipartFile
类:http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/commons/CommonsMultipartFile.html
当一个多部分表单提交给你的控制器时,Spring会解析表单,构建一个实现CommonsMultipartFile
的类的对象(可能是MultipartFile
)并使用这个对象作为参数调用你的控制器方法。
所以你不需要实现CommonsMultipartFile
方法,它们已经被Spring实现了。
答案 3 :(得分:0)
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()
}