Search code examples
javaspringthymeleaf

Post Object with List of Object containing multipart files


I'm trying to send a post request from Thymeleaf to my controller. The page dynamically creates new input fields when a button is pressed and the page can have multiple of these fields.

function addNewRow(){
    let row = document.createElement("tr");
    let data = document.createElement("td");
    let floorData = document.createElement("td");
    let imageData = document.createElement("td");
    let floorInput = document.createElement("input");
    let imageInput = document.createElement("input");
    row.setAttribute("id","newAdditions");
    floorInput.setAttribute("id","floorNumber");
    floorInput.setAttribute("type", "text");
    floorInput.setAttribute("placeHolder", "Floor Number");
    floorInput.setAttribute("class", "form-control floorNumber");
    floorData.setAttribute("id", "floorNumberData")
    floorData.appendChild(floorInput);
    imageInput.setAttribute("type","file");
    imageInput.setAttribute("accept","image/*");
    imageInput.setAttribute("id","imageData");
    imageInput.setAttribute("class","imageData");
    imageData.appendChild(imageInput);
    row.appendChild(data);
    row.appendChild(floorData);
    row.appendChild(imageData);
    document.getElementById("tableBody").appendChild(row);
  }

Now when the submit button is pressed, the images (imageData) is passed into a List along with the floorNumber

function submitImages(){
    let allItems = document.querySelectorAll('[id=newAdditions]');
    for(let i = 0; i < allItems.length; i++){
      let floor = allItems[i].getElementsByClassName('floorNumber');
      let image = allItems[i].getElementsByClassName('imageData');
      floor[0].setAttribute("name", "images[" + i +"].floorNumber");
      image[0].setAttribute("name", "images[" + i +"].floorImage");

    }
    $('#floorForm').submit();

  }

My @ModelAttribute/Dto class is as below

public class UploadFormDto{

    private List<UploadData> images;

    private Long id;

getters & setters
}

UploadFormDto contains

public class UploadData{

    private MultipartFile floorImage;

    private String floorNumber;

getters & setters
}

And my controller method is as below

 @PostMapping(value = "/edit")
 @Transactional
 public String handleEditHotelRooms(@ModelAttribute("editForm") UploadFormDto editForm,
                                       @PathVariable("hotelId") Hotel hotel,
                                       BindingResult result, RedirectAttributes redirectAttributes) throws WebActionException {}

ISSUE: When the form is sent through, the list of objects populate the floorNumber correctly but the file is never sent through. What am i doing wrong or missing?

My thymeleaf page does not have the enctype='multipart/form-data' because if I add it, the controller complains that the "Current request is not a multipart request"


Solution

  • So i finally managed to fix this, the issue was not in the js or the DTO. The issue was on the Thymeleaf page itself, i had "ajax-form=true" in the form attribute of the page. Once that was removed, I was able to submit the form correctly and get all the images to the controller.