Spring MVC和多部分处理

时间:2013-11-21 18:35:14

标签: spring spring-mvc

我正在使用Spring MVC 4,我有一个带有以下映射/方法的控制器:

@RequestMapping(value = "/me/bio", method = RequestMethod.POST, consumes = { "multipart/form-data" })
@ResponseBody
public JsonResponse<Boolean> saveProfileBio1(Account account, @RequestPart("file") MultipartFile file, @RequestPart("profile") @Valid ProfileBio profileBio) throws ValidationException, IOException {
...//code here
}

当我提交多部分表单数据请求时,它失败并出现HTTP 400错误请求,错误为“org.springframework.web.multipart.support.MissingS ervletRequestPartException:所需的请求部分'配置文件'不存在”

以下是原始请求:

------WebKitFormBoundarynU961NKt3K534rCg
Content-Disposition: form-data; name="profile"
{"profileName":"Zack Smith","profileDescription":"xxx","profileWebLink" :"www.abc","profilePictureUrl":"https://s3.amazonaws.com/xxx-images/default.png","profileTitle":"CTO1"}
------WebKitFormBoundarynU961NKt3K534rCg
Content-Disposition: form-data; name="file"; filename="2013-11-16 21.19.59.jpg"
Content-Type: image/jpeg 

正如您所看到的,请求明确具有“个人资料”部分。从我的调试,问题是“配置文件”请求部分没有“Content-type”设置,DefaultMultipartHttpServletRequest具有以下方法,需要设置它,如果它返回null,整个请求失败,上面的错误

@Override
public HttpHeaders getMultipartHeaders(String paramOrFileName) {
String contentType = getMultipartContentType(paramOrFileName);
if (contentType != null) {
 HttpHeaders headers = new HttpHeaders();
 headers.add(CONTENT_TYPE, contentType);
 return headers;
}
else {
 return null;
}
}

麻烦的是我似乎找不到在浏览器中为每个部分设置FormData提交的内容类型的方法,而且似乎是我无法设置的东西,而Spring似乎需要它。

有关如何解决此问题的提示或是否存在错误?

由于

2 个答案:

答案 0 :(得分:2)

我看到两个解决问题的方法:

  1. 在客户端上:如上所述here,将JSON作为Blob添加到FormData。背景:Blob允许设置内容类型(带角度js的示例):

    var formData = new FormData();
    formData.append('profile', new Blob([angular.toJson(profile)], {
      type: "application/json"}
    ));
    
  2. 另外在服务器上(不推荐):覆盖getMultipartHeaders的{​​{1}}方法,并在春季进行配置。如果您正在使用DefaultMultipartHttpServletRequest,则还需要覆盖它(由于缺少依赖注入点):

    CommonsMultipartResolver

答案 1 :(得分:0)

我正在与这个问题作斗争,我的解决方案是停止使用@RequestPart并使用@RequestParam代替。如果我正确理解@RequestPart的文档,它只能用于几种类型的开箱即用(例如MultipartFile),但其他类型需要HttpMessageConverter。还要确保声明了MultipartResolver bean。建议它返回CommonsMultipartResolver