将 Angular 中的图像上传到 Spring Boot

Upload images from Angular to SpringBoot

我花了几个小时尝试将图像从 Angular 发送到 SpringBoot。现在我收到这个错误:

org.springframework.web.multipart.MultipartException: Current request is not a multipart request

前端(Angular)代码如下所示:

  saveProduct(productSave: ProductSave, mainImg: File, imageList: File[]): Observable<any>
  {
    const formData = new FormData();
    const formListData = new FormData();

    formData.append('mainImg', mainImg, mainImg.name);

    imageList.forEach( img => formListData.append('imageList', img));

    return this.httpClient.post<ProductSave>(this.saveUrl, {productSave, mainImg, imageList});
  }

mainImg 和 imageList 是用户上传的图片,初始化如下:

mainImg = event.target.files[0];
imageList.push(event.target.files[0]);

我的后端 (SpringBoot) 代码如下所示:

    @PostMapping("/save")
    public void saveProduct(@RequestBody ProductSave productSave, @RequestParam("mainImg")MultipartFile main, @RequestParam("imageList")MultipartFile[] multipartFiles)
    {
        System.out.println(productSave.getProduct().getName());
    }

我真的不知道如何发送这些图像,我试图查看堆栈但我失败了。

感谢您的帮助!

问题出在 Spring 引导控制器方法参数中。

在多部分请求中,您可以发送 JSON 请求正文。相反,您必须发送键值对。

因此,您有 2 种方法可以做您想做的事 -

  1. 发送JSON字符串然后反序列化。

Spring 引导 API 示例:-

    @PostMapping("/save")
        public String create(@RequestPart("file")MultipartFile multipartFile, @RequestPart("files") List<MultipartFile> multipartFiles, @RequestPart("jsonString") String jsonString) {
/** To convert string to POJO        
 com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
        
                 ProductSave productSave = this.objectMapper.readValue(jsonString,ProductSave.class); **/
                return jsonString;
       }

HTML/Javascript 样本:-

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <input type="file" id="file">
  <button onclick="submitData()">Submit Data</button>
  <script type="text/javascript">
    function submitData() {
      const formData = new FormData();
      const fileField = document.querySelector('input[id="file"]');

      formData.append('jsonString', JSON.stringify({document: {data: 'value'}}));
      formData.append('file', fileField.files[0]);
      Array.from(fileField.files).forEach(f => formData.append('files', f));

      fetch('http://localhost:8080/save', {
        method: 'POST',
        body: formData
      })
      .then(response => response.json())
      .then(result => {
        console.log('Success:', result);
      })
      .catch(error => {
        console.error('Error:', error);
      });
    }
    
  </script>
</body>


在前端:-

JSON.stringify(product);
  1. 将文件作为字节数组发送,在这种情况下您不需要在前端使用表单数据。

您可以在前端使用以下方法将文件对象转换为字节数组:-

const fileToByteArray = async (file) => {
  return new Promise((resolve, reject) => {
    try {
      let reader = new FileReader();
      let fileByteArray = [];
      reader.readAsArrayBuffer(file);
      reader.onloadend = (evt) => {
        if (evt.target.readyState === FileReader.DONE) {
          const arrayBuffer = evt.target.result;
          const array = new Uint8Array(arrayBuffer);
          array.forEach((item) => fileByteArray.push(item));
        }
        resolve(fileByteArray);
      };
    } catch (e) {
      reject(e);
    }
  });
};

application.properties 中尝试设置以下 -

spring.servlet.multipart.max-file-size=1024KB
spring.servlet.multipart.max-request-size=1024KB
spring.http.multipart.enabled=false

玩转 max-file-size