Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC file upload controller - I'd like the controller to be called as soon as the upload starts

Using a naked servlet's doPost, when a file upload starts, doPost is immediately called. I can then stream the files from the request object using the commons FileItemIterator.

Using Spring MVC, I can't seem to get the controller method to fire until after the file(s) have all been received by the server, which is not ideal.

I want my servlet/controller method to process as many files as it can and perform some rollback operations if an upload is interrupted. I can't do that with Spring MVC currently.

public void doPost(HttpServletRequest request, HttpServletResponse res){
//I can immediately stream the response here 
}

vs.

@RequestMapping(value="/uploadFiles", method= RequestMethod.POST)
public @ResponseBody String addFiles(ContentManagerTicket ticket, HttpServletRequest request){
//I can't do anything until the files are received - whether i use a HttpServletRequset or MultiPartFile
}

Any ideas? Thanks!

like image 780
Dan Avatar asked Jun 24 '14 13:06

Dan


People also ask

How would you handle the situation where a user uploads a very large file through a form in your Spring MVC application?

A new attribute "maxSwallowSize" is the key to deal this situation. It should happen when you upload a file which is larger than 2M. Because the 2M is the default value of this new attribute .

What is default controller in Spring MVC?

The default handler is based on the @Controller and @RequestMapping annotations, offering a wide range of flexible handling methods. With the introduction of Spring 3.0, the @Controller mechanism also allows you to create RESTful Web sites and applications, through the @PathVariable annotation and other features.


1 Answers

You want streaming file uploads however when using Spring’s multipart (file upload) support it uses the classic approach. This basically means that all multipart parts of a request are parsed before the request is actually handed down to the controller. This is needed because a MultipartFile can be used as method argument and for this to work it needs to be available to the controller.

If you want to handle streaming file uploads you will have to disable Spring's multipart support and do the parsing yourself in the controller, the same way you would do in a servlet.

@Controller
public class FileUploadController {

    @RequestMapping("/upload")
    public void upload(HttpServletRequest request) {
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart) {
            // Inform user about invalid request
        }

        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload();

        // Parse the request
        FileItemIterator iter = upload.getItemIterator(request);
        while (iter.hasNext()) {
            FileItemStream item = iter.next();
            String name = item.getFieldName();
            InputStream stream = item.openStream();
            if (item.isFormField()) {
                System.out.println("Form field " + name + " with value "+ Streams.asString(stream) + " detected.");
            } else {
                System.out.println("File field " + name + " with file name " + item.getName() + " detected.");
            // Process the input stream
            ...
            }
        }
    }
}

See also how to upload a file using commons file upload streaming api and Apache commons fileupload "Streaming API"

like image 130
M. Deinum Avatar answered Oct 07 '22 00:10

M. Deinum