使用JSON的Spring MVC Multipart请求

Sun*_*mar 65 spring 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);
}
Run Code Online (Sandbox Code Playgroud)

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

任何人都可以帮我解决这个问题吗?

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

Sun*_*mar 165

这就是我用JSON数据实现Spring MVC Multipart Request的方法.

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

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

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);
}
Run Code Online (Sandbox Code Playgroud)

前端(JavaScript)代码段:

  1. 创建一个FormData对象.

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

    1. 如果已使用"file"类型的输入元素上载文件,则将其附加到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将无法填写请求的边界参数.

Javascript代码:

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"
            }));
Run Code Online (Sandbox Code Playgroud)

请求详情:

method: "POST",
headers: {
         "Content-Type": undefined
  },
data: formData
Run Code Online (Sandbox Code Playgroud)

请求有效负载:

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--
Run Code Online (Sandbox Code Playgroud)

  • @SunilKumar是否必须为ConnectionProperties指定Converter?如果我对连接属性使用上面显示的pojo,则会得到... HttpMediaTypeNotSupportedException:不支持内容类型'application / octet-stream'如果将POJO更改为String,则可以正常工作。因此,尚不清楚如何转换为POJO? (3认同)
  • @SunilKumar,如果我需要将文件上传作为可选..?使用表单数据。我该怎么做。因为如果未选择图像,则会收到“所需的请求部分文件不存在” (2认同)
  • 精彩,从5-6小时就坚持这个问题.终于从你的答案得到解决方案.jordar bhai .. (2认同)

moh*_*ohi 10

这必须奏效!

客户(角度):

$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;
        }
      };
Run Code Online (Sandbox Code Playgroud)

后端 - 弹簧启动:

@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
Run Code Online (Sandbox Code Playgroud)