【问题标题】:Multipart request spring does not bind file data多部分请求spring不绑定文件数据
【发布时间】:2014-09-01 15:50:28
【问题描述】:

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

控制器

@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 但文件是一个长字符串。

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.

感谢您的时间和帮助

罗伊

【问题讨论】:

  • 尝试使用@RequestPart 而不是@RequestParam 作为MultipartFile 参数。
  • @M.Deinum 感谢您的回复。已经尝试了所有可能的组合,包括将@RequestParam 更改为@RequestPart。没用
  • 如果它不起作用,您的配置就有缺陷。一切都是StringString[] 的事实并不奇怪,因为这就是Web 的工作方式,之后会转换参数。但是,它应该是 @RequestPart 而不是 @RequestParam,从 String 到请求类型的转换在两者之间的处理方式完全不同。确保您使用调试信息进行编译,否则请尝试@RequestPart(value="file"), required=false) 进行调试,您可以尝试使required 为真(并查看吐出什么错误)。
  • @M.Deinum 我也猜测我的配置存在缺陷,但无法真正理解是什么,只有一个 bean(据我所知)需要为 multipart 定义请求,我处理了它。我按照你的建议做了,并将所需的部分添加到文件中,但例外是......帮助不大/-:

标签: android spring spring-mvc multipart okhttp


【解决方案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 为图像时,默认传输编码为二进制。也许这是 okHttp 的一个小错误?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-17
    • 2020-10-12
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 2013-02-10
    相关资源
    最近更新 更多