Issue
Before upgrading java and jetty to version 11 (from version 8), I had an embedded jetty server that accepted upload requests. I just upgraded, and now I handle requests like this ( Which is very similar to before ):
@Path("/")
public class FilesRestService {
@POST
@Path("/files/upload")
@Produces("application/json")
@Consumes("multipart/form-data")
public WebapiResult<FileUploadResponse> uploadFile() {
return getFilesImpl().uploadFile();
}
}
And then in uploadFile()
method, I set the multipart config like this:
if (request.getContentType().startsWith("multipart/")) {
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, new MultipartConfigElement("/storage/tmp"));
}
List<Part> multipartItems = new ArrayList<>();
try {
multipartItems = (List<Part>) request.getParts();
} catch (Exception e) {
logger.error("Error uploading file: ", e);
}
[... here I obtain the parts and get the file one ( part )]
String fileFinalPath = "/storage/userfiles/uploadedFIle.txt";
// Moves file
File destFile = new File(fileFinalPath);
try (InputStream input = part.getInputStream()) {
boolean movedSuccessfully = Files.copy(input, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) > -1;
if (movedSuccessfully) {
return fileFinalPath;
} else {
return "";
}
}
Doing this, I find the file moved in the final folder correctly, however, while debugging and while it is uploading, I do not see the file in the temp folder, even if the file is large, so I wonder if it is using the right multipart config.
I also read that the annotation @MultipartConfig
should be used but I am using embedded jetty so I cannot make it work ( Not that I found of at least ).
The other problem is that I cannot find a way to implement a progress listener with embedded jetty 11, because doing request.getParts()
just remains stuck until all files are uploaded.
I am currently using jetty version 11.0.6
How can I achieve the progress listener and the correct file upload?
EDIT: After some additional research, i came across some articles like this that say that upload monitoring should not be done server side, but it can be done in the request, so client side...is this the right approach? Still though, the problem that i do not see the tmp uploaded files remains.
Solution
In your example code you are heading in the right direction.
if (request.getContentType().startsWith("multipart/")) {
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT,
new MultipartConfigElement("/storage/tmp"));
}
Two things to note.
Only use multipart/form-data
as the content-type, anything else in the multipart/*
space is unaffected by HttpServletRequest.getParts()
and the MultipartConfigElement
. (eg: multipart/byteranges
)
Next, properly configure the MultipartConfigElement
.
Set the maximum sizes to properly write the file to disk when it crosses the threshold you have configured there. (IIRC, the default is to keep it entirely in memory)
As far as progress on upload, yes, you are correct. The best place to do that is on the client side.
how to monitor progress of uploading file in servlet 3.1
Answered By - Joakim Erdfelt
Answer Checked By - David Marino (JavaFixing Volunteer)