Kepes
Kepes

Reputation: 59

Upload images from Angular to SpringBoot

I was trying for hours to send images from Angular to SpringBoot. Now I'm getting this error:

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

Frontend(Angular) code looks like this:

  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 and imageList are images uploaded from user, and initialized like so:

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

My backend (SpringBoot) code looks like this:

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

I really don't have idea how to send those images, I was trying to look around stack but I faild.

Thanks for any help!

Upvotes: 0

Views: 1927

Answers (2)

Kevzz8.15.17
Kevzz8.15.17

Reputation: 46

The problem is in the Spring Boot Controller method Arguments.

In multipart request, you can send the JSON Request body. Instead, you will have to send, key-value pairs.

So, you have 2 ways to do what you want to do -

  1. Send JSON String and then deserialize it.

Spring Boot API Sample :-

    @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 Sample: -

<!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>


And in front end:-

JSON.stringify(product);
  1. Send Files as Byte Arrays, You don't need to use form data in frontend in this case.

You can convert file object to byte arrays in frontend using:-

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);
    }
  });
};

Upvotes: 2

SOUMEN K
SOUMEN K

Reputation: 478

in the application.properties try setting up the following -

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

Play around with the max-file-size.

Upvotes: 0

Related Questions