Single and Multiple File Uploads with Jersey and Bootique

You'll find information on uploading single and multiple files with Jersey in many places, but there are a few details I'll emphasize in this post which may prove helpful to you. The full source for this post can be found in my File Upload and Download with Jersey Demo App on GitHub. Screenshots of the demo app functions are found in this post.

Here's the Multiple File Upload page from the Demo App. We're using the Bootstrap FileStyle enhancement for the sweet-looking File Input controls and simple JavaScript to add and remove Input controls.

The Controller method handling the upload is shown below. Notice we're receiving a List<FormDataBodyPart> as a parameter. You will often see a FormDataContentDisposition parameter on upload methods which looks like this.

@FormDataParam("file") FormDataContentDisposition fileDetail

But you can get the file details directly from the BodyPart like the filename as we're doing with bodyPart.getContentDisposition() below.

A couple of details that are interesting. (1) is more of a gotcha than a tip, as you want to be sure to read the value of the BodyPart as a FILE. If you retrieve it as an InputStream and process the stream you will end up with file corruption on save.

Along those lines, at (2) we are COPYING the temporary file we just retrieved from the BodyPart. This is because Jersey first saves the file to /tmp as you see in the first entry of the directory listing below. The file naming scheme is MIMExxxxxxxxxxxx.tmp.

You could actually retrieve that file directly through Reflection which would look like this.

So using Apache FileUtils.copy() is a bit more elegant…

Supporting File Upload in Jersey

Before finishing up it's important to remember that you have to add Multipart support to Jersey as laid out in the Jersey Documentation.

First add the dependency.


Then register the MultiPart feature with Jersey. The Jersey Documentation has a couple of examples on that. If you're using Bootique this is what registering the feature would look like in your Module Config.

Source Code Notes for this Post

Source code discussed in this post is found in my File Upload Download in Bootique Jersey Demo app on GitHub.