Empty MultipartFile[] when sending files from Vue to SpringBoot controller

Related searches

I'm doing a program that will help me to make monthly reports and I stuck at uploading photos which I need for one kind of the reports. For some reason, it doesn't get an array in the controller. I use Springboot RestController at the backend and Vue with BootstrapVue and vue-resource on the other side.

index.html (BootstrapVue):

  <b-form-file
    v-model="photos"
    accept="image/*"
    multiple
    placeholder="..."
  ></b-form-file>

  <b-button @click="uploadPhotos">Upload</b-button>

inside vuemain.js:

  data: {
    photos: null,
  },
  methods: {
    uploadPhotos(){
    var formData = new FormData();
    formData.append("photos", this.photos);
    this.$http.post('reports/photo', formData).then(result => {
      ...
    })
  }, ...

inside Controller:

@PostMapping("/photo")
public void addPhoto(@RequestParam("photos") MultipartFile[] photo) {
    System.out.println(photo.length); // shows 0
}

what I see inside Params at browser:

XHRPOSThttp://localhost:8080/reports-maker/reports/photo
[HTTP/1.1 500  326ms]
Request payload 
-----------------------------4469196632041005505545240657
Content-Disposition: form-data; name="photos"
[object File],[object File],[object File],[object File]
-----------------------------4469196632041005505545240657--

So for some reason at this point @RequestParam("photos") MultipartFile[] photo it's empty array. But if I change it to just one photo like this: @RequestParam("photos") MultipartFile photo and send one from js: formData.append("photos", this.photos[0]); everything works nicely and photo gets uploaded to the server.

It's my first experience with Vue and to be honest I don't want to go deep into JS learning, so probably there is some silly mistake somewhere. Any way I can use a loop in JS method to upload them one by one, but that would be so ugly. I hope there is a better way to do it (without any additional JS libraries of course).

If you use axios then you should add header

var headers = {
    'Content-Type': 'multipart/form-data',
};

axios.post(
    'reports/photo', 
    formData,
    {
        headers: headers,
    }
)
...

to be able send files to the server.

Spring Boot Multipart File upload example, If you use axios then you should add header var headers = { 'Content-Type': ' multipart/form-data', }; axios.post( 'reports/photo', formData, { headers: headers, } ) . – FilesStorageService helps us to initialize storage, save new file, load file, get list of Files’ info, delete all files. – FilesController uses FilesStorageService to export Rest APIs: POST a file, GET all files’ information, download a File. – FileUploadExceptionAdvice handles exception when the controller processes file upload.

I found an acceptable solution here https://stackoverflow.com/a/33921749/11508625 Rossi Robinsion's code works nicely. At least it looks better than sending files in separate requests one by one.

The answer is based on using getFileNames() which helps to iterate on files inside a request even if they are not in the array.

Uploading Files with Spring Boot, For some reason, it doesn't get an array in the controller. I Empty MultipartFile[] when sending files from Vue to SpringBoot controller. In the tutorial, we guide how to build a SpringBoot web-application to Upload/Download MultipartFile to FileSystem using Bootstrap 4 & JQuery Ajax

I agree, sending files in separate requests one by one is very "ugly", but I also don't like the idea of not using the mapping resources of Spring Boot, having to send all files with different names (seems disorganized) and having to work with MultipartHttpServletRequest, but there is a simple solution for this: Ian's answer to this question (not realy related to Vue.js, but useful) worked for me:

In order for Spring to map items in a request to a list, you need to provide the same name (in the FormData.append calls) for each item when appending to the form data. This allows Spring to effectively see the request as name=value1&name=value2&name=value3 (but obviously in the form of form data). When Spring sees the same key ("name") multiple times, it can map the values into a collection.

In your .vue file, append the photos with the same name:

for (let i = 0; i < this.photos.length; i++) {
    formData.append("photos", this.photos[i]);
}

And in your Controller:

@PostMapping("/photo")
public void addPhoto(@RequestParam("photos") MultipartFile[] photo) {
    System.out.println(photo.length); // Should be greater than 0 now
}

Note: I used Vue Axios to consume my API and manually added the Content-Type: multipart/form-data header. Make sure its in your request header list.

Spring Boot File Upload Example with MultipartFile, – FilesController uses FilesStorageService to export Rest APIs: POST a file, GET all files' information, download a File. –� Upload files to Servlet containers, application need register a MultipartConfigElement class. But Spring Boot makes it more easy by configuring it automatically. In this tutorial, we’re gonna look at way to build an Angular 4 App Client to upload/get MultipartFile to/from Spring Boot RestApi Server.

In certain applications, we might even want to send a file to another user, etc. Multipart-file requests break large files into smaller chunks which makes it efficient for Spring MVC application which consists of a Controller , a Service for backend uploadFiles(@RequestParam("files") MultipartFile[] files, RedirectAttributes� SpringBoot Upload/Download Files Example – MultipartFile + Thymeleaf + Bootstrap 4 In the tutorial, we guide how to build a SpringBoot web-application to upload/download file with Thymeleaf engine and Bootstrap 4.

to build an example to upload multiple files in Spring Boot with MultipartFile IOException; @Controller public class UploadingController { public static final� You want a target folder to which to upload files, so you need to enhance the basic UploadingFilesApplication class that Spring Initializr created and add a Boot CommandLineRunner to delete and re-create that folder at startup.

Transfer the received file to the given destination file. This may either move the file in the filesystem, copy the file in the filesystem, or save memory-held contents to the destination file. If the destination file already exists, it will be deleted first.

Comments
  • is your API allowed to post Array Datatype or just object?
  • Thanks, but I don't :(
  • @Hexronimo, it looks like it is something wrong with b-form-file component. Check if b-form-file component has inside string 'multipart/form-data'.