Search code examples
javascriptspringmultiple-file-upload

Upload multiple files each with additional information in spring


I'm new to spring boot and js and i'm trying to upload multiple files each having additionl information like description etc.

Objects :

public class BookDto {
    private String title;
    private String author;
    private List<PageDto> pageDtoList;
    // getters setters
}

public class PageDto {
    private String description;
    private MultipartFile file;
    // getters setters
}

Controller :

public class UploadController{

    @PostMapping("/upload")
    public ResponseEntity createGenre(@RequestBody BookDto bookDto){
       // do something with data
    }
}

Html :

<form action="upload" method="post" enctype="multipart/form-data">
    <input type="file" multiple onclick="postRequest(event)">
    <input type="submit" value="Upload" name="submit">
</form>

JS :

function postRequest(event){
    event.preventDefault();
    var files = [].slice.call(event.target.files);
    var pageList = [];
    for (var i=0; i<files.length; i++) { 
        pageList.push(new Page( i + "some description",files[i]));
    }
    var newBook = new Book();
    newbook.pageList = pageList;
    book.author = "author1";
    book.title = "title1";
    $.ajax({
        type: "POST",
        data: // i don't really know what to put here,
        url: "/upload",
        success: function (response) {
            // success
        },
        error: function (result) {
            // error
        }
    });

}

function Book(title, author, chapter, pageList){
    this.title = title;
    this.author = author;
    this.pageList = pageList;
}

function Page(description, file) {
    this.description = description;
    this.file = file;
}

I would like to know if it is possible to upload files as described by the objects or do i have to upload them seperately.


Solution

  • In order to create a book instance from a request, considering you have a route such as :

    @PostMapping("/createBook")
        public ResponseEntity createBook(@RequestBody BookDto bookDto){
           // do something with data
        }
    

    you can from client proceed to following :

    
    const book = {
       author: "George Orwell",
       title: "1984",
       pageDtoList: []
    };
    
    $.ajax({
            type: "POST",
            data: book,
            url: "/createBook",
            success: function (response) {
                // success
            },
            error: function (result) {
                // error
            }
        });
    

    You can then add pages with same logic, but with a file set to null temporary, and upload file after, given a page id.

    @PostMapping("/addPageToBook")
        public ResponseEntity addPage(@RequestParam("bookid") String bookId, 
                                      @RequestBody PageDto pageDto){
    
           // add a page instance to your book
        }
    

    And after you can set page content :

    @PostMapping("/setPageContent")
        public ResponseEntity setPage(@RequestParam("bookid") String bookId, 
                                      @RequestParam("pageid") String pageId,
                                      @RequestParam("file") MultipartFile content){
    
           // set content to page, ensure book dto is updated with last page instance
        }
    

    You will need to use https://developer.mozilla.org/en-US/docs/Web/API/FormData for AJAX uploading, but maybe (depending on your use case) a simple file input button + submit can be enough.