在SpringBoot应用程序中,使用Jquery和FormData将表单字段和上载的文件提交给SpringMVC控制器

在SpringBoot应用程序中,使用Jquery和FormData将表单字段和上载的文件提交给SpringMVC控制器,jquery,ajax,spring-mvc,spring-boot,form-data,Jquery,Ajax,Spring Mvc,Spring Boot,Form Data,我无法使用Jquery和FormData在Spring Boot应用程序中提交表单字段并将文件上载到Spring MVC控制器 我一直在控制器端收到这样一个异常“当前请求不是一个多部分请求” 我的设置 我有一个常规的Spring Boot Web应用程序 这是我的spring启动版本: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo

我无法使用Jquery和FormData在Spring Boot应用程序中提交表单字段并将文件上载到Spring MVC控制器

我一直在控制器端收到这样一个异常“当前请求不是一个多部分请求”

我的设置

我有一个常规的Spring Boot Web应用程序

这是我的spring启动版本:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.7.RELEASE</version>
</parent>
只有json提交工作绝对正常(当我只提交entityJsonStr而不是FormData实例时)

在服务器端,我的控制器如下所示:

@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
    }
}
我已经尝试了以下所有组合,没有任何效果

// 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,
但是没有任何东西可以正确提交formdata+文件

几天来我一直在努力让它发挥作用。。。我看不出我做错了什么

如果有人能做到这一点,请分享解决方案

更新:

在Jny回复后,我试着

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

现在我得到:(

我的请求负载如下所示:

------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--

找到了解决方案!!而且现在可以工作了!Yippe:)

我们需要做的是,当我们在FormData中设置Json字符串时,我们需要指定该部分为Json的内容类型。。。。现在的解决方案是这样的:

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
    }
});
然后控制器看起来和前面一样

还有一个变化,我最终为我的实体所做的。因为我现在将这个新的表单字段作为“image”,它不打算直接作为实体中的属性

所以我让Jackson忽略那些未映射的属性

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

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

现在可以了,我可以用ajax提交表单以及表单数据和文件。

**请注意,WebResponse是我的自定义响应类。如果您的请求不是多部分请求,则会出现错误。。。你认为这是什么意思?您可能需要更改内容类型标题?我尝试了标题:{'content-type':'multipart/form data'}和contentType:'multipart/form data',现在我得到:(FileUploadException:请求被拒绝,因为未找到多部分边界我的请求负载如下:---WebKitFormBoundaryPG92Ng6h630YkJKN内容处置:表单数据;name=“表单数据”{“id”:“,“name”:“s”,“code”:“s”/…more json}------WebKitFormBoundaryPG92Ng6h630YkJKN内容处置:表单数据;name=“image”;filename=“ThumbsUp.jpg”内容类型:image/jpeg-------WebKitFormBoundaryPG92Ng6h630YkJKN--我在上述实现中遇到以下错误:由于被认为是客户端错误,服务器无法或不会处理请求(例如,格式错误的请求语法、无效的请求消息框架或欺骗性的请求路由)。


org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
------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--
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
    }
});
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

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