Reputation: 89
I've recently inherited a Java API and am having trouble with file uploads. Unfortunately, Java isn't a language I have much experience in so I'm a bit stumped by this.
The MultiPartFile
is being received ok, and I can find the file in the temp directory, but when I try to use File.transferTo() to create the final file I just get the below error;
java.nio.file.NoSuchFileException: C:\Users\myUser\AppData\Local\Temp\undertow3706399294849267898upload -> S:\Dev\PolicyData\Temp.xlsx
As I mentioned the temp undertow file exists, and the directory on the S drive also exist, (but there's no Temp.xlsx as my understanding is this should be created by transferTo()
). Any solutions I've found to this problem so far are resolved using absolute file paths.
This is a simplified version of the code but the error remains the same.
SpringBoot framework is "1.5.3.RELEASE", running Java 1.8.0_131
ResponseEntity handleFileUpload(@RequestPart(name = "file") MultipartFile file, @PathVariable Long stageFileTypeId) {
if (!file.isEmpty()) {
try {
String filePath = "S:\\Dev\\PolicyData\\Temp.xlsx";
log.info("Upload Path = {}", filePath);
File dest = new File(filePath);
file.transferTo(dest);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(filePath));
}
catch (Exception ex) {
log.error("An error has occurred uploading the file", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
else {
log.error("An error has occurred, no file was received");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
If you need any more information please let me know.
Thanks, Neil
Upvotes: 1
Views: 3881
Reputation: 2947
The API for MultipartFile is a bit tricky. The transferTo(File) method javadoc states that (bold are mine):
This may either move the file in the filesystem, copy the file in the filesystem, or save memory-held contents to the destination file. If the destination file already exists, it will be deleted first.
If the target file has been moved in the filesystem, this operation cannot be invoked again afterwards. Therefore, call this method just once in order to work with any storage mechanism.
It seems that the Undertow implementantion already called it to move the in-memory uploaded file to "C:\Users\myUser\AppData\Loca\Temp\undertow3706399294849267898upload" so another transferTo is failing.
I came across the same problem using javax.servlet.http.Part in a Wildfly containter with Undertow.
If you are using Spring framework >= 5.1, you could try the Multipart.transferTo(Path) method, using dest.toPath()
Or you can copy from the inputStream, with something like this:
try (InputStream is = multipartFile.getInputStream()) {
Files.copy(is, dest.toPath());
}
Upvotes: 2