I have a form that is supposed to upload multiple files.
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" multiple="true">
</form>
My backend is Java/Spring. When this form is submitted, MultipartHttpServletRequest always contains a single file even when no file was selected.
My controller signature looks like
public String post(HttpServletRequest request, PageModel model, UiUtils uiUtils)
And inside the method I’m checking if the request is an instance of multipart request and cast it to MultipartHttpServletRequest.
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
savePatientFilesAslComplexObs(multipartRequest, encounter);;
When I used MultipartHttpServletRequest directly as a method parameter, it was always null. But casting it works.
My saveFiles method looks like
private void savePatientFilesAslComplexObs(MultipartHttpServletRequest request) throws IOException{
List<MultipartFile> multipartFiles = request.getMultiFileMap().get("file");
for (MultipartFile multipartFile: multipartFiles) {
InputStream in = multipartFile.getInputStream();
ComplexData complexData = new ComplexData(multipartFile.getOriginalFilename(), in);
Concept concept = RegistrationUtils.getComplexConceptForPatientFiles();
Obs obs = new Obs(encounter.getPatient(), concept, encounter.getEncounterDatetime(), encounter.getLocation());
obs.setComplexData(complexData);
obs.setEncounter(encounter);
Context.getObsService().saveObs(obs, "");
}
}
I ran my code through a debugger and placed a break point in the saveFiles method and noticed the loop is always executed even when no file is selected. So executed the following expressions to try and understand what is happening.
request.getMultiFileMap()
That returns a LinkedHashMap with one item whose key is “file”.
request.getFileNames().hasNext()
That returns true instead of false.
request.getFileMap().size()
Returns 1.
To look at the file which included in the request, I executed
request.getMultiFileMap().get("file")
That returns an instance of CommonsMultipartFile. See image below for details of how this object looks like
Because of the ghost file, handler.saveObs() throws an exception when I save the form without selecting any file.