frank
frank

Reputation: 1201

vue how to post list with files to spring

Srping boot 2.x and vue 2.x.

My UI looks like(not the complete picture for simplicity) :

enter image description here

my java bean is:

public class Attachment {

    private Integer eaId;

    private Integer eId;

    private String description;

    private MultipartFile file;

    //setters and getters

}
public class Booking {

    private Integer id;

    private String eNo;

    private List<Attachment> attachmentList;

    //some other fields

}

Each attachment item contains file and file description.

My front-end is:

<tr v-for=" (a, index) in eb.attachmentList" v-bind:key="index">

 <td><input type="text" v-model="a.description" /></td>

 <td><input type="file" v-on:change="selectFile(index, $event)" /></td>

 <td><i class="far fa-trash-alt fa-lg" v-on:click="delAttachment(index)" style="color: red"></i>

</td>

</tr>   

my spring controller is:

@PostMapping("/upload")
public Booking upload(@ModelAttribute Booking b) {

    //....
}

the vue code is:

var vm = new Vue({
  el: '#test',
  data() {
    return {
      eb: {
        'attachmentList': []
      }
    }
  },

  methods: {    

    selectFile(index, e) {

      this.eb.attachmentList[index].file = e.target.files[0];
    },

    saveTest() {

      var formData = new FormData();

      //how to populate formData ?

      axios.post("/tf/upload",
          formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }
        ).then(function() {
          //....
        })
        .catch(function(error) {
          //...
        });
    }

  }
});

I want to post this form data to spring controller with axios, that is convert form data to java bean Booking and the file list of form to List<Attachment> attachmentList of Booking.

It seems that I have to use FormData, right?

My problems is:

How to populate the FormData in my case?

If just upload file, I can use formData.append('file', file) then post it with header multipart/form-data directly.

But now there are a few file list and each file associated with its description. I don't know how to do such that I can get the form data in my spring controller.

Upvotes: 0

Views: 788

Answers (1)

Augusto Escobar
Augusto Escobar

Reputation: 36

In Vue side:

First, you need to create a new object of type FormData and append to it a reference for the input element that you are appending the file to.

HTML:

<input type="file" @change="processFile($event)">

Vue:

methods: {
  processFile(event) {
    this.myFile = event.target.files[0]
  }
}

This will do myFile variable hold a reference to the appended file.

When the time to upload comes:

const formData = new FormData();
formData.append('attribute-name-spring-expects', this.myFile, this.myFile.name);
// other attributes

Then, send this form data with axios like this:

const requestConfig = { 
  headers: { 'content-type': 'multipart/form-data' }
}

axios.post(url, formData, requestConfig);

Upvotes: 1

Related Questions