带有 JSON 的 Spring MVC 多部分请求

新手上路,请多包涵

我想使用 Spring MVC 发布一个包含一些 JSON 数据的文件。所以我开发了一个休息服务

@RequestMapping(value = "/servicegenerator/wsdl", method = RequestMethod.POST,consumes = { "multipart/mixed", "multipart/form-data" })
@ResponseBody
public String generateWSDLService(@RequestPart("meta-data") WSDLInfo wsdlInfo,@RequestPart("file") MultipartFile file) throws WSDLException, IOException,
        JAXBException, ParserConfigurationException, SAXException, TransformerException {
    return handleWSDL(wsdlInfo,file);
}

当我使用 content-Type = multipart/form-data or multipart/mixed 从其他客户端发送请求时,我得到下一个异常: org.springframework.web.multipart.support.MissingServletRequestPartException

谁能帮我解决这个问题?

我可以使用 @RequestPart 将 Multipart 和 JSON 发送到服务器吗?

原文由 Sunil Kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 679
2 个回答

这就是我使用 JSON 数据实现 Spring MVC 多部分请求的方式。

带有 JSON 数据的多部分请求(也称为混合多部分):

基于 Spring 4.0.2 Release 中的 RESTful 服务,可以使用@RequestPart 实现第一部分为 XML 或 JSON 格式数据,第二部分为文件的 HTTP 请求。下面是示例实现。

Java 片段:

Controller 中的 Rest 服务将混合使用 @RequestPart 和 MultipartFile 来为此类 Multipart + JSON 请求提供服务。

 @RequestMapping(value = "/executesampleservice", method = RequestMethod.POST,
    consumes = {"multipart/form-data"})
@ResponseBody
public boolean executeSampleService(
        @RequestPart("properties") @Valid ConnectionProperties properties,
        @RequestPart("file") @Valid @NotNull @NotBlank MultipartFile file) {
    return projectService.executeSampleService(properties, file);
}

前端(JavaScript)片段:

  1. 创建一个 FormData 对象。

  2. 使用以下步骤之一将文件附加到 FormData 对象。

    1. 如果文件是使用“文件”类型的输入元素上传的,则将其附加到 FormData 对象。 formData.append("file", document.forms[formName].file.files[0]);
    2. 直接将文件附加到 FormData 对象。 formData.append("file", myFile, "myfile.txt");formData.append("file", myBob, "myfile.txt");
  3. 使用字符串化的 JSON 数据创建一个 blob,并将其附加到 FormData 对象。这会导致多部分请求中第二部分的 Content-type 为“application/json”而不是文件类型。

  4. 向服务器发送请求。

  5. 请求详细信息:

Content-Type: undefined 。这会导致浏览器将 Content-Type 设置为 multipart/form-data 并正确填充边界。手动设置 Content-Type 为 multipart/form-data 将无法填写请求的边界参数。

脚本代码:

 formData = new FormData();

formData.append("file", document.forms[formName].file.files[0]);
formData.append('properties', new Blob([JSON.stringify({
                "name": "root",
                "password": "root"
            })], {
                type: "application/json"
            }));

请求详细信息:

 method: "POST",
headers: {
         "Content-Type": undefined
  },
data: formData

请求负载:

 Accept:application/json, text/plain, */*
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryEBoJzS3HQ4PgE1QB

------WebKitFormBoundaryvijcWI2ZrZQ8xEBN
Content-Disposition: form-data; name="file"; filename="myfile.txt"
Content-Type: application/txt

------WebKitFormBoundaryvijcWI2ZrZQ8xEBN
Content-Disposition: form-data; name="properties"; filename="blob"
Content-Type: application/json

------WebKitFormBoundaryvijcWI2ZrZQ8xEBN--

原文由 Sunil Kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议

这必须工作!

客户(角度):

 $scope.saveForm = function () {
      var formData = new FormData();
      var file = $scope.myFile;
      var json = $scope.myJson;
      formData.append("file", file);
      formData.append("ad",JSON.stringify(json));//important: convert to JSON!
      var req = {
        url: '/upload',
        method: 'POST',
        headers: {'Content-Type': undefined},
        data: formData,
        transformRequest: function (data, headersGetterFunction) {
          return data;
        }
      };

后端-Spring Boot:

 @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody
    Advertisement storeAd(@RequestPart("ad") String adString, @RequestPart("file") MultipartFile file) throws IOException {

        Advertisement jsonAd = new ObjectMapper().readValue(adString, Advertisement.class);
//do whatever you want with your file and jsonAd

原文由 mohi 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题