Tagbangers Blog

SpringBoot + Embedded Tomcat : Why does my file uploaded to my entry form disappear even if I place it in the session?

Hi, this is Nidhi, a new member of Tagbangers.
I am just starting to learn Java, Spring Boot, AWS etc. without any prior coding knowledge. I have tons of questions, and there are so many things you won't get answers for with a simple Google search!
I am particularly struggling with not understanding how things work overall, for example, how a Spring application is built and deployed. So much is done in the background, that when something goes wrong, it's hard to troubleshoot without knowing quite a bit about the workings behind-the-scenes.
So today, I'm writing about a small issue I faced when working on one of my projects.

 

Project overview:

My application is built in Spring Boot. On local, I am using the embedded Tomcat server.
The project is a simple entry form with a few fields (name, address, etc.) and one of them is a file upload field. This form has three steps, so the file will be uploaded only at the last step. Until then, the file has to be held in session somehow.
My form class is as below:

@Getter
@Setter
public class ApplyForm implements Serializable {
//Other fields
private transient MultipartFile file;
}

As you can see, I have a Multipart file field.

My controller class is as below:

@Controller
@RequestMapping("/apply")
@SessionAttributes(types = ApplyForm.class)
@RequiredArgsConstructor
@SuppressWarnings("java:S1192")
public class ApplyController {
@GetMapping
public String init(Model model) {
   var form = new ApplyForm();
   model.addAttribute(form);
   return entry(model);
}
//Code in controller
}

 

I have added the form object into the session. However, when the user uploads the file and clicks submit on the first step of the form, the file disappears and a FileNotFound exception is thrown.

Even though I have stored the form object (and hence, ostensibly, the file I thought) in the session, why does this happen?

It seems the answer is that my file is getting stored in a temporary directory created by Tomcat on startup (under /tmp), and this directory is deleted when the request in which it was stored is over.

Solution:

You can either write the file in-memory using spring.servlet.multipart.location in application.properties, but this would overwhelm the memory resources of the server if there are too many files being uploaded.

So the solution I adopted was to store the file in a temporary directory once uploaded in Step 1 of the form, and hold it there until the file is finally uploaded to an S3 bucket.