我可以在Spring Rest方法中混合媒体类型吗?

时间:2014-12-11 00:42:06

标签: java spring rest spring-mvc

我目前正在尝试编写一个接受文件上传的ReST方法。当用户提交文件时,我还希望他们添加描述,以及一些与文件内容有关的其他元数据(例如,"类型"与文件内容相关联) 。我使用Spring 4的Spring MVC Controller。

这是我想要做的一个例子:

@RequestMapping(value = "/file", method = RequestMethod.POST)
public @ResponseBody
ResponseEntity<MyFileDTO> uploadCustomAnnotationFile(
        @RequestParam("file") MultipartFile uploadFile,
        @RequestBody MyFileDetailsDTO fileDetails) {
    log.debug("This is working!");
}

但是,如果我尝试通过Swagger UI调用此方法,则会得到不受支持的媒体类型异常:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundarycAbgNBTQ09GQTBif' not supported

我怀疑我不能在1个请求中混合application / json和multipart / form-data?

更新: 基于zeroflagL的响应并遵循提供的链接到特定于我尝试做的文档,并使用@RequestPart而不是@RequestBody,我取得了很小的进展,但这仍然不是&#39工作。

新方法签名:

@RequestMapping(value = "/file", method = RequestMethod.POST)
public @ResponseBody
ResponseEntity<MyFileDTO> uploadCustomAnnotationFile(
        @RequestPart MultipartFile uploadFile,
        @RequestPart MyFileDetailsDTO fileDetails) {
    log.debug("This is working!");
}

新例外:

2014-12-11 09:21:45.237 [http-nio-8443-exec-8] ERROR c.i.h.c.ControllerExceptionHandler   [ControllerExceptionHandler.groovy:58] - Controller Exception
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'fileDetails' is not present.

提前致谢, 汤妮雅

2 个答案:

答案 0 :(得分:3)

您可以在Spring REST方法中混合媒体类型。 @ zeroflagL /回答也许是对的。但@RequestPart工作正常。这是我的代码,与你的代码没什么不同

<item>
  <Data>
    <tText>
      <string>6 resources every xxx should use tips #xl8</string>
    </tText>
    <tTime>
      <string>Tue Oct 28 09:43:22 +0000 2014</string>
    </tTime>
    <tText>
      <string>Tips for learning a new language </string>
    </tText>
    <tTime>
      <string>Fri Oct 24 16:35:30 +0000 2014</string>
    </tTime>
    <tText>
      <string>#Voiceover or #Subtitles</string>
    </tText>
    <tTime>
      <string>Thu Oct 23 17:34:15 +0000 2014</string>
    </tTime>
  </Data>
</item>

我建议你应该检查一下你的要求。不是你的服务器端代码。 这是我的测试预览代码(我使用Postman在Chrome中测试过)

@RequestMapping(value = "/interface/member/v1/register.do", method = RequestMethod.POST)
@ResponseBody
public RegisterResponse register(@RequestPart(value = "registerRequest") RegisterRequest registerRequest,
@RequestPart(value = "attachment", required = false) MultipartFile file) throws ServiceException {
    return memberV1Service.register(registerRequest, file);
}

请求中缺少Content-Type。此测试因 MissingServletRequestPartException 而失败原因所需请求部分&#39; registerRequest&#39;不存在。

您可以使用RESTClient或其他方法进行测试,并检查Content-Type是否存在。

答案 1 :(得分:1)

Spring documentation明确解释了该怎么做。

混合application / json和multipart / form-data 的想法是错误的,因为application/json将是multipart(sic!)请求的一部分。

WebKitFormBoundary让我认为您尝试从浏览器发送AJAX请求,我想知道您是否真的发送了JSON。 AFAIK它不可能显式添加一个(真正的)JSON部分,就像它在Spring文档中所示。也许你可以告诉我们客户代码。

无论如何,您无法使用@RequestBody,因为这会包含您要上传的文件。您必须使用@RequestPart。如果您发送表单数据(而不是JSON)以及文件,那么您根本不需要任何注释。