Announcement Announcement Module
Collapse
No announcement yet.
Handling a Multipart File Upload in a separate thread Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Handling a Multipart File Upload in a separate thread

    I posted this question on stackoverflow, but I wanted to post it here too. I have the following scenario:

    I want to upload a multipart file via Ajax to my Spring web app. When the server receives the POST request, it creates a ticket number in the database. It then starts a thread that handles the actual file upload. The server then returns the ticket number and an HTTP response code of 200 or 201.

    I am using the CommonsMultipartResolver to handle the request and I have set the resolveLazily flag to true so that the Multipart isn't resolved right away.

    Example:

    Code:
    @Controller
    public class myController{
    
        @RequestMapping(value = "/upload", method = RequestMethod.POST)
        @ResponseStatus(value = HttpStatus.OK)
        @ResponseBody
        public String upload(MultipartHttpServletRequest request, String fileName){
    
            String ticket = dao.createUploadTicket(fileName);
            Runnable run = new Runnable(){
    
                @Override
                public void run(){
    
                    dao.writeUpdate(ticket, "Getting data from request");
                    final MultipartFile file = request.getFile("theFile");
                    dao.writeUpdate(ticket, "Multipart file processed");
                    try {
                       dao.writeUpdate(ticket, "Saving file to disk");
                       file.transferTo(new File("/myDirectory"));
                       dao.writeUpdate(ticket, "File saved to disk");
                    }
                    catch(Exception e){
                       dao.writeUpdate(ticket, "File upload failed with the exception " + e.toString());
                    }
                }
            };
            Thread t = new Thread(run);
            t.start();
            return ticket;
        }
    }
    This is not the exact scenario I am trying to address, but it demonstrates what I want to do.

    The point here is that a client uploads a large file and will immediately get a response back, the ticket number. The client can then use the ticket number to look at the progress updates of the upload. Another use case is that I can have another page on the site that can query the DB for all ticket numbers and see a 'live' view of all file uploads that are taking place on the site.

    I have not been able to get this to work because as soon as the controller returns, Spring calls cleanupMultipart() in the CommonsMultipartResolver. Since the resolveLazily flag is set to false, when cleanupMultipart() is called, it will begin to resolve and initialize the multipart files. This leads to a race condition between the call to "request.getFile("theFile");" in the Runnable and the cleanupMultipart() call eventually leading to an exception.

    I am not sure if this is an acceptable way to handle file uploads since it appears that I am doing something fundamentally wrong in HTTP since I am returning a response code prior to receiving the entire data from the client.

    Can anyone advise on this?

  • #2
    I found the following blogs which may point in the right direction. I'll post back when I try some of it out.

    http://blog.springsource.org/2012/05...async-support/
    https://blogs.oracle.com/enterpriset...t_in_servlet_3

    Comment


    • #3
      You should read my next blog post regarding HTTP request-response semantics. You can't complete the response while there is still an upload. Purely based on your description, I'm not sure there is a way to do that.

      Comment

      Working...
      X