0

I know that there are plenty of questions covering the topic, but I cannot figure out how to achieve the following requirement.

I would like to upload a list of files, each one containing some extra information. In the java world this would mean the following:

@NoArgsConstructor
@Getter
public class SkillsVerificationData {

   String type; // this information is related to the file 
   MultipartFile file;
}

Question 1: Is this possible for a RestController to achieve such a mapping using a wrapper object? (See first answer of the referenced question- @ModelAttribute)

Question 2: Using the following controller method answered in the question referenced above

@RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = { "multipart/form-data" })
public void upload(@RequestPart("type") @Valid String type,
        @RequestPart("file") @Valid @NotNull @NotBlank MultipartFile file) {
}

I assume that it applies for a single file. How should the request parts be defined/described to achieve uploading a List<SkillsVerificationData> or SkillsVerificationData[] ?

Note that the client sends the information using FormData.

Thanks in advance!

Eirini Graonidou
  • 1,506
  • 16
  • 24

1 Answers1

3

If i understand your question correctly, you want to upload a list of files along with certain information specific to each file. I can correlate with an example to bring more clarity. A user wants to upload a list of candidates' technical profiles or resumes along with candidate information. If that is the case, you can create an array of MultiPart file and a json structure which contains information about each unique fileName, with unique id and candidate information in a json structure. If that is the requirement, you can refer below the code.

@PostMapping(
      value = "/multiUpload",
      consumes = {MediaType.MULTIPART_FORM_DATA_VALUE},
      produces = MediaType.TEXT_PLAIN_VALUE)
  public ResponseEntity<?> uploadingMultipleFiles(
      @RequestParam("files") MultipartFile[] uploadingFiles, @RequestPart(value = "emps", required = true) String empJsonTxt) {
      System.out.println("EMP as Json String = " + empJsonTxt);
      //Process the empJsonTxt
    ObjectMapper objectMapper = new ObjectMapper();
    try {
      Employee emp = objectMapper.readValue(empJsonTxt, Employee.class);
      System.out.println("Now emp = " + emp);
    } catch (IOException e) {
      e.printStackTrace();
    }
    for (MultipartFile uploadedFile : uploadingFiles) {
      System.out.println("Uploaded File Name = " + uploadedFile.getOriginalFilename());
      File file = new File("E:/sure-delete/" + uploadedFile.getOriginalFilename());

    //Upload functionality
      try {
        uploadedFile.transferTo(file);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return ResponseEntity.ok("All Files uploaded successfully ...");
  }

In this case empJsonTxt is a string of json contents which contains all the required information about the employees and their resume/profile. Multipart files will be used only for uploading. However, you can extrapolate this part to make suitable to your requirement. This is doable, there may be many more good approaches also.

Sambit
  • 7,625
  • 7
  • 34
  • 65
  • hey Sambit, thank you for your response, I updated my question to make it more clear. This kind of mapping between the file and the filename(they belong together) would be quite essential. – Eirini Graonidou May 28 '19 at 20:08
  • If you want single file upload with extra information, it can be achieved. it becomes complex when you upload multiple files with extra information. There are lot of answers, but some do not work. I tried this one my project and it worked. Hope my information is useful to you. – Sambit May 28 '19 at 20:11
  • I ended up implementing a solution similar to yours, as I think it is not possible to define the content type for each request part. That is the problem in this case. If you modify your answer so that it answers my question, I would also accept it. – Eirini Graonidou Jun 11 '19 at 18:04