Thursday, February 26, 2015

java.lang.IllegalStateException.IllegalStateException:File has been moved - cannot be read again Reson

I am using Spring MVC in a web application. I have a view where I allow users to upload a file, and I would like to preserve this file between subsequent views
  
 @RequestMapping("/loadFile")  
   public String loadFile(  
       Model model,   
       @RequestParam(required = true) CommonsMultipartFile uploadedFile,  
 HttpServletRequest request, HttpSession session)   
 {  
 //some process  
 model.addAttribute("file", uploadedFile);  
 }  

So my next view should have the file "accesible". I tried to replicate the form of my file upload view and then assign this file value to the file input like this:
But this assigns a value of org.springframework.web.multipart.commons.CommonsMultipartFile@57836c9d or something similar, and it does not work.

So My second approach was to put the multipartFile into Session Object to make it available across multiple request.


For example:

 HttpSession session = ... // get the session, you have it in your handler method  
 CommonsMultipartFile uploadedFile = ...; // same as above  
 session.setAttribute("UPLOADED_FILE", uploadedFile);   

Now as long as your session is valid, ie. hasn't timed out or been invalidated, any Controller or servlet can access this object
 CommonsMultipartFile uploadedFile = session.getAttribute("UPLOADED_FILE");  

If the uploaded file exceeds maxUploadSize (default maxUploadSize is 10Kb), this approach will also give 'IllegalStateException:File has been moved - cannot be read again'. As file will be stored in disk directly instead of storing it in memory on exceed of maxUploadSize. File is written to temp folder of servlet container and will be deleted as soon as request scope ends. So, If you try to access the MultipartFile after end of request scope, It will check actual existence of temporary file. Since the temp file has been deleted after end of request scope. It can't read data from CommonsMultipartFile object. 

So, Instead of putting multipart data object in session object, put multipartFile inputStream session object.