0

I need to send a file and an entity to my server, my server is a spring boot app:

@PostMapping("/upload")
public void upload(@RequestParam("dto") MyDto dto,
                      @RequestParam("file") MultipartFile file) {
    ...
}

MyDto.java:

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDto implements Serializable {

    private String f1;
    private String f2;

}

And my client:

FormDataMultiPart formDataMultiPart = new FormDataMultiPart();

FileDataBodyPart fileDataBodyPart = new FileDataBodyPart("file",
                new File("C:/dev/test.txt"),
                MediaType.APPLICATION_OCTET_STREAM_TYPE);

 MyDto dto = new MyDto();
 dto.setF1("f1");
 dto.setF2("f2");

 final FormDataMultiPart multipart = (FormDataMultiPart) formDataMultiPart
                .field("dto", dto, MediaType.APPLICATION_JSON_TYPE) // if I change to string type works fine;
                .bodyPart(fileDataBodyPart);

Response response = ClientBuilder.newClient()
    .target(String.format("%s%s", "http://localhost:8080", "/api/upload"))
    .register(MultiPartFeature.class)
    .request(MediaType.APPLICATION_JSON)
    .header("Authorization", "Bearer " + token.getToken())
    .post(Entity.entity(multipart, multipart.getMediaType()));

response -> InboundJaxrsResponse{context=ClientResponse{method=POST, uri=http://localhost:8080/api/upload, status=500, reason=Internal Server Error}}

So, someone have an ideia what's wrong?

fdam
  • 820
  • 1
  • 11
  • 25

1 Answers1

1

You need to create a wrapper class to get the file along with the form data and bind it with your form.

public class MyDtoWrapper implements Serializable {

    private String f1;
    private String f2;
    private MultipartFile image;

}

Controller

@PostMapping("/api/upload/multi/model")
public ResponseEntity<?> multiUploadFileModel(@ModelAttribute MyDtoWrapper model) {
    try {
           saveUploadedFile(model.getImage()); // Create method to save your file or just do it here
           formRepo.save(mode.getF1(),model.getF2()); //Save as you want as per requirement 
        } catch (IOException e) {
           return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    return new ResponseEntity("Successfully uploaded!", HttpStatus.OK);
}

For complete example look here.

UsamaAmjad
  • 4,175
  • 3
  • 28
  • 35
  • I forgot to mention that in the client-side I am using jersey to upload the data. So, what would be equivalent to spring Multipart class on the client-side? I tried FormDataMultiPart and FormDataMultiPart but both cases I got a MessageBodyWriter error. Still looking for a solution but considering using something like: @RequestParam("f1) String f1, RequestParam("f2) String f2, @RequestParam("file") MultipartFile file, seems a code-smells but works seamlessly. – fdam Jan 15 '19 at 11:37
  • In that case I think you will need to create different parameters. I would suggest you to read this detailed answer https://stackoverflow.com/a/27614403/4704510 – UsamaAmjad Jan 16 '19 at 00:20