Uploading a file to Jersey REST API using JQuery

There’s the traditional way of uploading a file using Java servlets. In this post, I’m going to walk through how you can do this with a REST API to keep a clean separation between frontend and backend.

Client-side
This should be familiar html. We set up a form to upload a file like so

<form enctype="multipart/form-data" method="post" action="../rest/file">
  <div class="form-group">
    <label for="uploadfile"><b>File</b></label>
    <input type="file" name="uploadfile">
  </div>
  <p>
  <input type="submit">
  <p>
</form>

This will make a POST request to “../rest/file” with the file.

Now let’s see how we can do the same with JQuery

$(document).ready(function() {
  $('#submitJquery').click(submitForm);
});      

function submitForm() {
  var file = $('input[name="uploadfile"').get(0).files[0];

  var formData = new FormData();
  formData.append('uploadfile', file);

  $.ajax({
      url: "../rest/file",
      type: 'POST',
      xhr: function() {  // Custom XMLHttpRequest
        var myXhr = $.ajaxSettings.xhr();
        return myXhr;
      },
      // beforeSend: beforeSendHandler,
      success: function(data) {
        alert('successfully uploaded file with '+data+' lines');
      },
      // Form data
      data: formData,
      //Options to tell jQuery not to process data or worry about content-type.
      cache: false,
      contentType: false,
      processData: false
    });
}

In the html, make sure you have a submit link to bind to

<a id="submitJquery" href="#">Submit via JQuery</a>

Take care to note the FormData object. And that’s all there is to it.
Now, why would we want to do this? Maybe you want to add additional fields to send. In which case, you can add more key/values by adding to the FormData like so

formData.append('key1','value1');
formData.append('key2','value2');
...

Server-side
Now, let’s take a look at what needs to be done on the jersey server-side.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

@Path ("/file")
public class FileResource {
  @POST
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  @Produces(MediaType.TEXT_PLAIN)
  public Response uploadFile(@FormDataParam("uploadfile") InputStream uploadedInputStream,
                             @FormDataParam("uploadfile") FormDataContentDisposition fileDetail) {
    try (
      BufferedReader reader = new BufferedReader(new InputStreamReader(uploadedInputStream));
    ) {
      int numLines = 0;
      String line = null;
      while( (line = reader.readLine()) != null ) {
        numLines++;
        System.out.println(line);
      }
      return Response.ok(Integer.toString(numLines), "text/plain").build();
    } catch (final Exception e) {
      throw new WebApplicationException(e);
    }
  }
}

The things to note are the MediaType.MULTIPART_FORM_DATA and the @FormDataParam parameters.
If you wanted to accept the additional “key1” and “key2” values, then just add two more parameters to the method signature like so:

  public Response uploadFile(@FormDataParam("uploadfile") InputStream uploadedInputStream,
                             @FormDataParam("uploadfile") FormDataContentDisposition fileDetail,
                             @FormDataParam("key1") String value1,
                             @FormDataParam("key2") String value2) {

Thanks for reading.

Check out this post on how to send and receive arrays of values with the same key name here.

Advertisements
Tagged , , ,

3 thoughts on “Uploading a file to Jersey REST API using JQuery

  1. lazaropj says:

    Tks man… Simple and working…

  2. le says:

    Thanks a lot. This is stuff i am looking for

  3. VivR says:

    Super man . This was very simple and exactly what I was looking for…Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: