Here's what I'm doing. I want to upload 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.
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.
So here's something along the lines of what I have
@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;
}
}
So the point here is that the ticket number can be used to get the progress updates. Say a large file is being uploaded. The client that made the file upload POST (say in this instance an Ajax request) can do it asynchronously and get back a ticket number. The client can the use that ticket number to determine the stage of the file upload and display information in another page.
One other use is that I can have an HTML page that makes a request to the server for all ticket numbers, then shows a "live" view of all the file uploads that are taking place on the server.
I haven't 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.
Anyone have any ideas? Am I breaking some kind of HTTP contract here by wanting to do back-end asynchronous file handling.