0

I want to be able to download a file from a legacy service through a middle-layer Spring Web service. The problem currently is that I am returning the contents of the file and not the file itself.

I've used FileSystemResource before, but I do not want to do this, since I want Spring to only redirect and not create any files on the server itself.

Here is the method:

@Override
public byte[] downloadReport(String type, String code) throws Exception {
    final String usernamePassword = jasperReportsServerUsername + ":" + jasperReportsServerPassword;
    final String credentialsEncrypted = Base64.getEncoder().encodeToString((usernamePassword).getBytes("UTF-8"));
    final HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add("Accept", MediaType.APPLICATION_JSON_VALUE);
    httpHeaders.add("Authorization", "Basic " + credentialsEncrypted);
    httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
    final HttpEntity httpEntity = new HttpEntity(httpHeaders);
    final String fullUrl = downloadUrl + type + "?code=" + code;

    return restTemplate.exchange(fullUrl, HttpMethod.GET, httpEntity, byte[].class, "1").getBody();
}
Deniss M.
  • 3,617
  • 17
  • 52
  • 100
  • *The problem currently is that I am returning the contents of the file and not the file itself*: what does that mean? What are you doing, what do you expect to happen, and what happens instead? – JB Nizet Sep 03 '17 at 11:53
  • I am trying to download a file located in another web service. I want to download the file. I am getting the raw contents of the file displayed. – Deniss M. Sep 03 '17 at 12:00
  • That answers the "what happens instead" part. What do you *expect* to happen? – JB Nizet Sep 03 '17 at 12:02
  • A regular file download should be initiated. – Deniss M. Sep 03 '17 at 12:02
  • So, return a ResponseEntity, and make sure to set its content type header (so that the browser knows what kind of file it's downloading), and the Content-disposition header telling the browser which file name it should suggest/use (for example "attachment; filename=yourfile.pdf") – JB Nizet Sep 03 '17 at 12:10
  • Thanks, I solved the problem. The file name part is still work in progress from the other service side. – Deniss M. Sep 03 '17 at 12:12

1 Answers1

0

Turns out I was missing this annotation parameter in my *Controller class:

produces = MediaType.APPLICATION_OCTET_STREAM_VALUE

The whole method of the controller should look like this:

@RequestMapping(value = "/download/{type}/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<?> downloadReport(@PathVariable String type, @PathVariable String id) throws Exception {
        return new ResponseEntity<>(reportService.downloadReport(type, id), HttpStatus.OK);
    }
Deniss M.
  • 3,617
  • 17
  • 52
  • 100