简体   繁体   中英

Spring boot MultipartFile methods

In Spring Boot, we use MultipartFile to send files from a client to a server. Here's an example of how to use it:

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

I know that MultipartFile is an interface, which makes all of its members (ie getName ) abstract. What I don't understand is, how am I supposed to use this interface without creating an implementation for it myself?

If you look at Spring sources, you'll find CommonsMultipartFile , which implements methods such as getName()

When you declare that you want to receive a MultipartFile , you don't actually care how it's implemented behind the scenes. You only care about the file. Spring Framework will decide which implementation to provide you with.

Other interesting implementation is MockMultipartFile , which may be used during tests. Again, since it implements the same interface, you don't need to change your methods in any way.

Since it's an interface, someone needed to provide the implementation. In this case, Spring provides it at runtime.

How Spring MVC handles file uploads is explained in the relevant section of the Spring Reference Guide.

When a request comes in it first reaches the DispatcherServlet , it will detect that it is a multipart request and with that delegate the request processing to a configured MultipartResolver (which is again an interface). The DispatcherServlet detects this MultipartResolver by a well known name multipartResolver (this is hardcoded in the DispatcherServlet ).

What this MultipartResolver instances do is wrap the actual HttpServletRequest into a MultipartServletRequest (which is a Spring MVC extension to the HttpServletRequest) and this wrapper knowns how to handle the incoming request and create the appropriate MultipartFile` implementations.

Spring has 3 flavors of this interface

  1. CommonsMultipartResolver using Apache Commons FileUpload
  2. StandardServletMultipartResolver using the Servlet 3.0 standard Servlet API file upload
  3. MockMultipartFile for unit testing

When using Spring Boot to handle file uploads it configures by default the second option the StandardServletMultipartResolver .

Now when the complex processing of the multipart request is done, the DispatcherServlet passes on the request to the selected handler (ie your controller). The RequestMappingHandlerAdapter inspects the selected request handling method and will fill in all method arguments.

In the end it is the RequestParamMethodArgumentResolver which binds an actual value to the MultipartFile object. Using the getFiles method on the MultipartServletRequest . For the default Spring Boot configured implementation (the StandardMultipartHttpServletRequest ) this will give instances of StandardMultipartFile which is an embedded class in said StandardMultipartHttpServletRequest

The advantage of being able to use the MultipartFile interface is that you could change to CommonsMultipartResolver without having to change your controller.

Spring has some class implementing MultipartFile interface. For example, there is CommonsMultipartFile class: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/commons/CommonsMultipartFile.html

When a multipart form is submitted to your controller, Spring parses the form, builds some object of class implementing MultipartFile (probably that CommonsMultipartFile ) and calls your controller method with this object as a parameter.

So you don't need to implement MultipartFile methods, they are already implemented by 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()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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