Receiving arrays from form elements with Jersey

You may have worked with Jersey before, and for the most part, writing a REST API has been as easy as writing a java API. So to accept an array of Strings, you could do something like this.

Jersey Code:

@Path("/rest/")
public class ServiceClass {

@GET
@Path("/strings")
public Response postStringArray(@QueryParam("keywords") List<String> inputList) {
...
}

HTTP Request:

GET http://example.com/rest/strings?keywords=Hello&keywords=World&keywords=...

And that would work fine. But what if you had to send an array from a form element (because you need to upload a file for example).

Suppose you had this form:

<form enctype="multipart/form-data" method="post" action="/rest/upload">
    Keyword: <input name="keywords" />
    Keyword: <input name="keywords" />
    Keyword: <input name="keywords" />

    File:
    <input type="file" name="file">
    <input type="submit" value="upload">
</form>

Then your Jersey API signature will have to consume MediaType.MULTIPART_FORM_DATA. So you’d think something like this will work

@POST
@Path("upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileAndKeywords(
    @FormDataParam("keywords") List<String> keywords,
    @FormDataParam("file") InputStream file_in,
    @FormDataParam("file") FormDataContentDisposition fileDetail) {
  ...
}

But you’ll run into a “wrong number of arguments” exception.

Instead, you’ll need to change the List declaration to something unintuitive like this

@POST
@Path("upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFileAndKeywords(
    @FormDataParam("keywords") List<FormDataBodyPart> keywords,
    @FormDataParam("file") InputStream file_in,
    @FormDataParam("file") FormDataContentDisposition fileDetail) {

      for(FormDataBodyPart keyword : keywords)
        System.out.println( keyword.getValueAs(String.class) );

}

I should note one last thing. If you’re posting the form attributes via jQuery, you’ll want to take advantage of the FormData object. But you should take care to post the array of keywords correctly.

For example, this is the wrong way of posting it

var formData = new FormData();
var keywords = [];
$('select[name="keywords"]').each(function() {
  if( $(this).val() )
    keywords.push($(this).val());
});
formData.append('keywords', keywords);
formData.append('file', $('input[name="file"]').get(0).files[0]);

And this would be the right way:

var formData = new FormData();
$('select[name="keywords"]').each(function() {
  if( $(this).val() )
    formData.append('keywords',$(this).val());
});
formData.append('file', $('input[name="file"]').get(0).files[0]);
Advertisements
Tagged ,

3 thoughts on “Receiving arrays from form elements with Jersey

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

  2. Vikas Mittal says:

    it worked for me

  3. thanksForHelping says:

    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: