1

We have a RestController with the below endpoint

@PostMapping(path = "/downloadFile", produces = MediaType.MULTIPART_FORM_DATA_VALUE, 
                  consumes = MediaType.APPLICATION_JSON_VALUE)
public FileDownloadResponse downloadFile(@RequestBody FileDownloadRequest request) {
     FileDownloadResponse downloadResponse = new FileDownloadResponse();

     File file = new File("c:/fileLocation/"+request.getFileName());
     try (InputStream stream = new FileInputStream(file)) {
        byte[] bytes = IOUtil.toByteArray(stream);
        downloadResponse.setFileName(file.getName());
        downloadResponse.setCheckSum(calculateCheckSum(bytes));
        downloadResponse.setFileContents(new FileSystemResource(bytes, file.getName()));
     } catch (Exception e) {
        e.printStackTrace();
     }
     return downloadResponse;
}

public class FileDownloadResponse {
     private String fileName;
     private Long checkSum;
     private Resource fileContents;
     
}

public static class FileSystemResource extends ByteArrayResource {

    private String fileName;

    public FileSystemResource(byte[] byteArray , String filename) {
        super(byteArray);
        this.fileName = filename;
    }

    public String getFilename() { return fileName; }
    public void setFilename(String fileName) { this.fileName= fileName; }

}

And on the Client Side we have the below code,

public class FileDownloadResponseClient {
     private String fileName;
     private Long checkSum;
     private MultipartFile fileContents;     
}

public FileDownloadResponseClient download(FileDownloadRequest request) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setAccept(Collections.singletonList(Mediatype.ALL));

    HttpEntity<FileDownloadRequest> requestEntity = new HttpEntity<>(request, headers);

    return restTemplate.postForEntity(downloadUrl, requestEntity, FileDownloadResponseClient.class);                                         

}

When we run the Rest Client above, we are getting the below error, org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 : [no body]

Is it possible to download a multipartfile along with other additional fields? If yes, what is that we are missing here, please let us know.

Thanks in Advance!

Sabari
  • 127
  • 1
  • 13
  • I'm afraid you got it wrong. You're supposed to upload the file via HTTP POST, e.g. by using `curl -v localhost:8080/downloadFile file=@filename`. Then in the controller you access the file content through `MultipartFile.getInputStream()`. Have a look at here: https://stackoverflow.com/a/60855693/7066647 – dbaltor Aug 02 '22 at 19:42
  • Hi - thank you for the comments! actually we are not uploading the file to the server instead downloading a file from the server and also sending few other attributes as part of the response. – Sabari Aug 08 '22 at 18:32
  • 1
    I see. You may find some good ideas in here: https://stackoverflow.com/questions/35680932/download-a-file-from-spring-boot-rest-service – dbaltor Aug 09 '22 at 07:46

1 Answers1

0

org.springframework.web.multipart has a method boolean isEmpty() to find if the file has no content. Best put that check there and redirect to a message about such a file multipart form. Of [no body] i have found that message on test requests to http server but in entirety generally means there is nothing in the form or no extra information needed for the server to complete the request. For now i presume the spring framework handles all the url decoding and boundary marker stripping (on both ends) of uploaded files.

Samuel Marchant
  • 331
  • 2
  • 6
  • The file is present and there are no exceptions on the server side while reading the file contents. However, on the client side, if we remove the line ```headers.setAccept(Collections.singletonList(Mediatype.ALL));``` we are getting a HttpStatus 406 'Not Acceptable', please note this is downloading the file from the server along with few other additional attributes. When we just download the file without any other additional fields, it works fine, in other words when the restcontroller end point returns ```ResponseEntity``` we are able to download it. – Sabari Sep 18 '21 at 10:20