I'm trying to upload files to my Spring Boot application and directly writing them to their destination (not in a temp file first). The application code I have works, but I can't get my unit test to work. My controller looks like this:
@PostMapping("/upload")
@ResponseBody
public String handleFileUpload(final HttpServletRequest request) throws IOException {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
throw new ResponseStatusException(BAD_REQUEST, "Input was not of type multipart");
}
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator fileIterator = upload.getItemIterator(request);
while (fileIterator.hasNext()) {
FileItemStream item = fileIterator.next();
if (!item.isFormField()) {
// Save the file
try {
return myFileStorageService.store(item.openStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
throw new ResponseStatusException(BAD_REQUEST, "Input did not contain a file");
}
This code works great, but my test doesn't:
@MockBean
private MyFileStorageService myFileStorageService;
@Autowired
private MockMvc mockMvc;
@Test
void shouldUploadFile() throws Exception {
final InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("testfile.txt");
final MockMultipartFile testFile = new MockMultipartFile("file", "testfile.txt", null, inputStream);
doReturn("success!").when(myFileStorageService).store(testFile);
mockMvc.perform(multipart("/upload").file(testFile))
.andExpect(status().isOk())
.andExpect(content().string("success!"));
verify(myFileStorageService).store(testFile);
}
This results in the following exception:
org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.init(FileItemIteratorImpl.java:189)
at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.getMultiPartStream(FileItemIteratorImpl.java:205)
at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.findNextItem(FileItemIteratorImpl.java:224)
at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.<init>(FileItemIteratorImpl.java:142)
at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:252)
at org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload.getItemIterator(ServletFileUpload.java:134)
at com.lolmewn.FileUploadController.handleFileUpload(FileUploadController.java:128)
...
And in my config, I have configured the following:
spring:
servlet:
multipart:
enabled: false
max-file-size: -1
max-request-size: -1
I expect Spring would generate the multipart boundaries for me, just like the browser or Postman do, is this not the case? I saw many similar questions, with most of them explicitly setting their content-type as the primary error, but as far as I know I'm not setting a content-type anywhere, so I expect Spring to generate it for me.