多部分请求弹簧不绑定文件数据

时间:2014-09-01 15:50:28

标签: android spring spring-mvc multipart okhttp

我遇到的问题是我为了将照片上传到服务器而编写的控制器。

控制器

@RequestMapping(value = "photos", method = RequestMethod.POST)
@ResponseBody
public Response uploadPhoto(@RequestPart PhotoMetaData data, 
                            @RequestParam String localName,
                            @RequestPart(required = false) MultipartFile file, 
                            HttpServletRequest request) {

    log.info("@uploadPhoto > ip of request: " + request.getRemoteAddr() + ", metaData: " + data);

    return photosService.storePhoto(data, file, localName);
}

问题是file为空但是在检查request参数时,请求显然有3个多部分参数,每个参数都有假设的contentType但文件是长字符串。

debug capturing

Android应用正在调用此代码。我正在使用OkHttp来构建多部分请求。代码:

MediaType jsonMediaType = MediaType.parse("application/json");
RequestBody requestBody = new MultipartBuilder()
             .type(MultipartBuilder.FORM)                                                                     
             .addPart(Headers.of("Content-Disposition", "form-data; name=\"data\""),                                         
              RequestBody.create(jsonMediaType, photoMetaDataStr))                                                                                                     
             .addPart(Headers.of("Content-Disposition", "form-data; name=\"localName\""),
              RequestBody.create(MediaType.parse("text/plain"), localName.getPath()))
             .addPart(Headers.of("Content-Disposition", "form-data; name=\"file\""),
              RequestBody.create(MediaType.parse("image/jpeg"), new File(localName.getPath())))
                                                    .build();

    Request request = new Request.Builder().url(url).post(requestBody).build();

    final Response response = client.newCall(request)
                                   .execute();

------编辑------------

相关豆类:

@Bean
public MultipartResolver multipartResolver() {

    return new CommonsMultipartResolver();
}

----编辑2 ----- 在更改控制器签名以便需要该文件后,我得到一个例外:

----编辑3 ------ 经过大量测试后,我注意到问题可能就是我使用okHttp将多部分请求发送到服务器的方式。使用Postman客户端,呼叫成功

error with request org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest@3d854606
org.springframework.web.multipart.support
.MissingServletRequestPartException: Required request part 'file' is not present.

感谢您的时间和帮助

罗伊

1 个答案:

答案 0 :(得分:1)

我能够通过向请求添加Content-Transfer-Encoding标头来解决问题。

RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
                                                    .addPart(Headers.of("Content-Disposition", "form-data; name=\"data\""),
                                                            RequestBody.create(jsonMediaType, GsonInstance.getInstance()
                                                                                                          .toJson(photoMetaData)))
                                                    .addPart(Headers.of("Content-Disposition", "form-data; name=\"file\"; filename=\"localName\"", "Content-Transfer-Encoding", "binary"),
                                                            RequestBody.create(MediaType.parse("image/jpeg"), new File(localName.getPath())))
                                                    .build(); 

我不确定为什么会这样。据我所知,当contentType是image时,默认传输编码是二进制的。也许这是okHttp的一个小错误?