1

I am unable to use Jquery and FormData to submit form fields and uploaded File to Spring MVC Controller in Spring Boot App.

I keep getting this exception "The current request is not a multipart request" on the controller side.

My Setup.

I have a regular Spring Boot Webapp

This is my spring boot version :

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.7.RELEASE</version>
</parent>

My Ajax form submit looks like this :

var entityJson = form2js("my-form-id",null,false); // js library to get json from form
var entityJsonStr = JSON.stringify(entityJson);

var formData = new FormData();
formData.append("data", entityJsonStr); // the entered data as JSON


// append files, if there are any
$.each($("#my-form-id").find("input[type='file']"), function(i, tag) {
    $.each($(tag)[0].files, function(i, file) {
       formData.append(tag.name, file);
    });
});

$.ajax({
    url:     theUrl,
    type:    'POST',
    headers: {'Content-Type': undefined},
    cache: false,
    processData: false,
    data:    formData,
    error: function(xhr,status,err){
        // failure handling
    },
    success: function(response){
        // success handling
    }
});

Only json submission works absolutely fine, (when I submit only entityJsonStr instead of FormData instance)

On Server-side my Controller looks like this:

@RequestMapping(value="/save", method= RequestMethod.POST, produces=APPLICATION_JSON_UTF_8)
public @ResponseBody WebResponse<MyEntity> save(
        @Valid @RequestPart(value="data") MyEntity myEntity
        ,@RequestPart(value = "image", required = false) MultipartFile image
) throws Exception {
    try {

        validateImage(image);
        saveImage(myEntity.getName() + ".jpg", image);

        shoppingCenterService.save(myEntity);
        MyEntity shoppingCenterWithOnlyId = getEmptyShoppingCenterWithId(myEntity.getId());

        return new WebResponse(true, SHOPPINGCENTER_SAVE_SUCCESS);
    } catch (DuplicacyException de) {
        return getDuplicacyResponse(de, myEntity);
    } catch(Exception e) {
        LOGGER.error("MyEntity Controller[save]", e);
        return new WebResponse(false, MYENTITY_SAVE_FAILED); // custom response
    }
}

when I not use @RequestPart and simply use @Valid @RequestBody MyEntity myEntity and don't use FormData object in javascript, i get the right json which translates to an object of MyEntity ...

I keep getting this exception :

org.springframework.web.multipart.MultipartException: The current request is not a multipart request   

I have tried all following combinations, nothing works

// dataType: 'json',
// contentType: 'application/json',

headers: {'Content-Type': undefined},
cache: false,
//  contentType: null,
//  processData: false,
// enctype: 'multipart/form-data',
processData: false,
//contentType: false,
//cache: false,

// async:   true,
// cache:   false,
// global:  false,

but nothing is submitting the formdata + file properly.

I have been trying to get this to work for a couple of days now ... I don't see what I am doing wrong.

If anybody has got this to work, please share a solution.

Update:

After Jny's reply, I tried with

headers: {'Content-Type': 'multipart/form-data'}

and

contentType:  'multipart/form-data'

Now I get :(

org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found

My Request Payload looks like this :

------WebKitFormBoundaryPG92Ng6h630YkJKN
Content-Disposition: form-data; name="form_data"

{"id":"","name":"s","code":"s" 
  // ... more json
}
------WebKitFormBoundaryPG92Ng6h630YkJKN
Content-Disposition: form-data; name="image"; filename="ThumbsUp.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryPG92Ng6h630YkJKN--
3
  • ** Please note that WebResponse is my custom response class Commented Nov 23, 2015 at 13:49
  • You get an error that your request is not multipart request... What do you think it means? May be you need to change your content-type header? Commented Nov 23, 2015 at 14:31
  • I tried with headers: {'Content-Type': 'multipart/form-data'} and contentType: 'multipart/form-data' Now I get :( FileUploadException: the request was rejected because no multipart boundary was found My Request Payload looks like this : ------WebKitFormBoundaryPG92Ng6h630YkJKN Content-Disposition: form-data; name="form_data" {"id":"","name":"s","code":"s" // ... more json } ------WebKitFormBoundaryPG92Ng6h630YkJKN Content-Disposition: form-data; name="image"; filename="ThumbsUp.jpg" Content-Type: image/jpeg ------WebKitFormBoundaryPG92Ng6h630YkJKN-- Commented Nov 23, 2015 at 14:56

1 Answer 1

3

Found the Solution !! and it works now Yippee :)

What we need to do is when we are setting the Json-string in the FormData, we need to specify the content-type that this part is json .... so the solution looks like this now :

var entityJson = form2js("my-form-id",null,false); // js library to get json from form
var entityJsonStr = JSON.stringify(entityJson);

var formData = new FormData();
formData.append("data", new Blob([entityJsonStr], {
                type : "application/json"  // ** specify that this is JSON**
            })); 


// append files, if there are any
$.each($("#my-form-id").find("input[type='file']"), function(i, tag) {
    $.each($(tag)[0].files, function(i, file) {
       formData.append(tag.name, file);
    });
});

$.ajax({
    url:     theUrl,
    type:    'POST',
    processData: false,
    contentType: false,
    cache: false,
    data:    formData,
    error: function(xhr,status,err){
        // failure handling
    },
    success: function(response){
        // success handling
    }
});

and then the controller looks the same as earlier.

There was one more change, that I ended up doing for my entity. Since I now have this new form field as "image" which was not meant to be a property in my entity directly.

So I asked Jackson to ignore those unmapped properties

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
// MyEntity class goes here {}

This works now and I am able to ajax submit the form with the form-data as well as the file.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm getting this error on above implementation: The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).</p><hr class="line" /><h3>Apache Tomcat/9.0.4</h3></body></html>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.