4

I'm trying to send files which is appended to FormData using jquery ajax. After referring some of mozilla and IBM's documents, I've came up with following.

ajax code:

var sessionId = $.cookie("referenceId");
var myFormData = { sessionId: sessionId,
                    cipherData: cipherData,   // Encrypted xml data
                    payslip: document.getElementById('payslip').files[0]};
var formData = new FormData();
for (var key in myFormData) {
    console.log(key, myFormData[key]);
    formData.append(key, myFormData[key]);
}
$.ajax({
    url : 'api/rootpath/childpath',
    type : 'POST',
    processData: false,
    contentType: false,    // Here the contentType is set to false, so what should I put at @Consumes in java code
    data : {
        formData: formData
    },
    success : function(data,status) {
        alert('success');
    },
    failure : function(data) {

    }
});

Java code:

@POST
@Path("/childpath")
@Consumes(MediaType.MULTIPART_FORM_DATA)  // I tried removing it, changing it to various formats, but none worked
public Response createLoan(@FormParam("cipherData") String cipherData,@FormParam("sessionId") String sessionId,
                           @FormParam("payslip") File payslip);

I've been trying this for a day. I do manage to receive the file by directly submitting the form of enctype="multipart/form-data", but I need to do it in ajax. If I look at my tomcat's log, it always gives me 415 status code when accessing api/rootpath/childpath. I think the problem is due to different content type received when comparing with original content type. I tried changing the MediaType. to "multipart/form-data" etc, but it failed.

The Coder
  • 2,562
  • 5
  • 33
  • 62

3 Answers3

7

Ok, finally figured out my mistake. I hope this answer will be greatly helpful for future visitos who wish to upload files using ajax in JAX-RS

Ajax code:

var myFormData = { sessionId: sessionId,
                    cipherData: cipherData,   // encrypted xmlData
                    payslip: document.getElementById('payslip').files[0]};
var formData = new FormData();
for (var key in myFormData) {   // Just to make sure everything set correctly, I would recomment to do like this
    console.log(key, myFormData[key]);
    formData.append(key, myFormData[key]);
}
$.ajax({
    url : 'api/rootpath/childpath',
    type : 'POST',
    data : formData,    // Do not send it as - data: { formData: formData }
    processData: false, // Tell jquery to don't process the data
    contentType: false, // If you do not set it as false, most probably you would get 400 or 415 error
    success : function(data,status) {
        alert('success');
    },
    failure : function(data) {

    }
});

Java code:

@POST
@Path("/childpath")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response createLoan(
         @FormDataParam("cipherData") String cipherData,  // encrypted xml data
         @FormDataParam("sessionId") String sessionId,   // sessionId (you can also get it through httpHeader)
         @FormDataParam("payslip") InputStream payslipS,  // this is your file
         @FormDataParam("payslip") FormDataContentDisposition payslipD ) {   // this is your file details like file name and file type

// If you need to store the file in DB as blob
byte[] byte = IOUtils.toByteArray(payslipS);   // IOUtils is org.apache.commons.io.IOUtils (you need to add its dependency in pom.xml or build.gradle)
// Now store the byte[] in Blob field of DB
return Response.status(200).entity('success').build();
}
The Coder
  • 2,562
  • 5
  • 33
  • 62
2

The Backend

415 Unsupported in this case most likely means there isn't a provider available to handle multipart

Multipart support is not standardized. You will need to add an implementation specific dependency and possibly (depending on the implementation), configure the support, and use the implementation specific mutlipart annotation (and it's not @FormaParam, which is for x-www-form-urlencoded data), or some other mulipart object.

Different support documentation and examples

The Front End

A bunch of different examples can be found here

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • 1
    After making some changes, I've got my expected workflow.. Will provide it as answer soon.. Thanks.. – The Coder Feb 23 '15 at 17:06
  • Added my answer, I think it would be helpful for future visitors.. Do tell me if I did any mistakes in it.. Anyhow, it's working for me.. – The Coder Feb 23 '15 at 19:18
0

I think you should change the contentType in your ajax snippet (where it currently says false) to "multipart/form-data", as this is the value for the Java constant MediaType.MULTIPART_FORM_DATA.

geert3
  • 7,086
  • 1
  • 33
  • 49