Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带JSON的Spring MVC多部分请求_Json_Spring_Spring Mvc - Fatal编程技术网

带JSON的Spring MVC多部分请求

带JSON的Spring MVC多部分请求,json,spring,spring-mvc,Json,Spring,Spring Mvc,我想使用SpringMVC发布一个包含一些JSON数据的文件。所以我开发了一个rest服务 @RequestMapping(value = "/servicegenerator/wsdl", method = RequestMethod.POST,consumes = { "multipart/mixed", "multipart/form-data" }) @ResponseBody public String generateWSDLService(@RequestPart("meta-da

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

@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);
}
当我使用从rest客户端发送请求时
content Type=multipart/form data或multipart/mixed
,我得到下一个异常:
org.springframework.web.multipart.support.MissingServletRequestPartException

有人能帮我解决这个问题吗

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

如文档所述:

当“多部分/表单数据”请求的一部分由 找不到它的名称

这可能是因为请求也不是多部分/表单数据 因为该部分不在请求中,或者因为web 应用程序未正确配置以处理多部分 请求——例如,没有多部分解析器


这就是我用JSON数据实现SpringMVC多部分请求的方式

包含JSON数据的多部分请求(也称为混合多部分): 基于Spring4.0.2版本中的RESTful服务,可以通过@RequestPart实现HTTP请求,第一部分为XML或JSON格式的数据,第二部分为文件。下面是示例实现

Java代码段: 控制器中的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)代码段:
  • 创建一个FormData对象

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

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

  • 将请求发送到服务器

  • 请求详细信息:
    内容类型:未定义
    。这将导致浏览器将内容类型设置为“多部分/表单数据”,并正确填充边界。手动将内容类型设置为多部分/表单数据将无法填写请求的边界参数

  • Javascript代码: 申请详情: 请求有效负载: 这一定有用

    客户(角度):

    后端Spring启动:

    @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
    

    我们在项目中看到,带有JSON和文件的post请求在前端和后端开发人员之间造成了很多混乱,导致了不必要的时间浪费

    这里有一个更好的方法:将文件字节数组转换为Base64字符串,并以JSON格式发送

    public Class UserDTO {
        private String firstName;
        private String lastName;
        private FileDTO profilePic; 
    }
    
    public class FileDTO {
        private String base64;
        // just base64 string is enough. If you want, send additional details
        private String name;
        private String type;
        private String lastModified;
    }
    
    @PostMapping("/user")
    public String saveUser(@RequestBody UserDTO user) {
        byte[] fileBytes = Base64Utils.decodeFromString(user.getProfilePic().getBase64());
        ....
    }
    
    将文件转换为base64字符串的JS代码:

    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function () {
    
      const userDTO = {
        firstName: "John",
        lastName: "Wick",
        profilePic: {
          base64: reader.result,
          name: file.name,
          lastModified: file.lastModified,
          type: file.type
        }
      }
      
      // post userDTO
    };
    reader.onerror = function (error) {
      console.log('Error: ', error);
    };
    

    您是否在servlet上下文中指定了
    org.springframework.web.multipart.commons.commons multipartresolver
    ?是的,它添加到my spring.xml中。干得好。如果需要将文件上载作为可选选项,我必须将
    processData:false、contentType:false
    JQuery$ajax()
    @SunilKumar一起使用..?与表单数据一起使用。我如何才能做到这一点。因为如果未选择图像,则获取的
    所需请求部分文件不存在
    对于我来说是“新Blob([JSON.stringify(…)]”part完成了。我已经准备好了所有其他内容。Thx。@SunilKumar您必须为ConnectionProperties指定转换器吗?如果我对ConnectionProperties使用如上所示的pojo,我会得到…HttpMediaTypeNotSupportedException:如果我将pojo更改为字符串,则不支持内容类型“application/octet stream”。因此,不清楚它是如何工作的正在进行到POJO的转换?只是想说明一下:MultipartFile方法参数上的
    @NotBlank
    注释实际上不会检查文件是否为空。仍然可以上载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;
            }
          };
    
    @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
    
    public Class UserDTO {
        private String firstName;
        private String lastName;
        private FileDTO profilePic; 
    }
    
    public class FileDTO {
        private String base64;
        // just base64 string is enough. If you want, send additional details
        private String name;
        private String type;
        private String lastModified;
    }
    
    @PostMapping("/user")
    public String saveUser(@RequestBody UserDTO user) {
        byte[] fileBytes = Base64Utils.decodeFromString(user.getProfilePic().getBase64());
        ....
    }
    
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function () {
    
      const userDTO = {
        firstName: "John",
        lastName: "Wick",
        profilePic: {
          base64: reader.result,
          name: file.name,
          lastModified: file.lastModified,
          type: file.type
        }
      }
      
      // post userDTO
    };
    reader.onerror = function (error) {
      console.log('Error: ', error);
    };