2

My API is as follows:

@ApiOperation(value = "Zip of all the documents the customer attached to their application (id and loan)", notes = "", response = Void.class, tags = {
    "Manage Customers/Applications",
})
@ApiResponses(value = {
    @ApiResponse(code = 200, message = "OK", response = Void.class)
})
@RequestMapping(value = idPath + "/files/customer-documents/zip",
    method = RequestMethod.GET)
@ResponseBody
void downloadCustomerDocumentsAsZip(HttpServletResponse response,
                                    @ApiParam(value = "Application ID", required = true) @PathVariable(value = "applicationId")
                                        Long applicationId);

The Rest Controller:

 @Override
public void downloadCustomerDocumentsAsZip(HttpServletResponse response,
                                           @ApiParam(value = "Application ID", required = true) @PathVariable(value = "applicationId")
                                               Long applicationId) {

    InputStream inputStream = new ByteArrayInputStream(manageApplicationsService.findCustomerDocumentsAsZip(applicationId));

    response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
    response.setHeader("Content-Disposition", "attachment; filename=zipFile.zip");
    try {
        FileCopyUtils.copy(inputStream, response.getOutputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }

}

The Response:

PK{i�Jtemp0+I�(Q(A%

Issue:

I want to download the zip file as an attachment, but the response is as above.

Note: I tried all the download methods which are explained on Rest Download Endpoints but none of them were successful. I also add

produces = MediaType.APPLICATION_OCTET_STREAM_VALUE

to the API definition but again no success.

So, I would be so grateful if anyone could help me with their genuine solution.

Arghavan
  • 1,125
  • 1
  • 11
  • 17
saeedj
  • 2,179
  • 9
  • 25
  • 38
  • I have actually posted an answer to this https://stackoverflow.com/questions/27952949/spring-rest-create-zip-file-and-send-it-to-the-client/50691612#50691612 on how to download pdf/zip from spring REST endpoint. – Raf Jun 05 '18 at 03:44

4 Answers4

1

I had the same issue. Changing Content-Type to MediaType.APPLICATION_PDF_VALUE triggered download action for me. But then "Save As" dialog display filename extension as .pdf by default.

With HttpServletResponse

        response.setContentType(MediaType.APPLICATION_PDF_VALUE);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
        response.setContentLength((int)contents.length);
        try {
            response.getOutputStream().write(contents);
            response.getOutputStream().flush();
        } catch (IOException e) {
            throw new BadRequestException("Could not generate file");
        }

Of if you use ResponseEntity

    byte[] contents = fileContent.getBytes();
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
    responseHeaders.add(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_PDF_VALUE);
    return new ResponseEntity<byte[]>(contents, responseHeaders,HttpStatus.OK);
Gokhan Celikkaya
  • 716
  • 1
  • 7
  • 17
  • You are very welcome. Consider cleaning up now ... and removing no longer required comments, too ;-) – GhostCat Sep 12 '17 at 09:03
0

You can just return a ResponseEntity<byte[]> in your controller. Add Content-Type and Content-Disposition headers to your response so that it opens properly.

    public ResponseEntity<byte[]> downloadCustomerDocumentsAsZip(
        @ApiParam(value = "Application ID", required = true)
        @PathVariable(value = "applicationId") Long applicationId) {

    byte[] bytes = manageApplicationsService.findCustomerDocumentsAsZip(applicationId);
    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add("Content-Type", "application/octet-stream");
    headers.add("Content-Disposition", "attachment; filename=\"zipFile.zip\"");
    return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
   }
Tim
  • 41
  • 4
  • For this answer i am wondering should there be any Messageconverter for the 'byte[]' type? If so, which one do I need? As I tried to apply the code but my files always end up being corrupt when I download them. (I am not using spring boot). – Jasper Lankhorst Aug 20 '18 at 14:26
0

According to HttpServletResponse doc: calling flush() commits the response. I think you need to call response.getOutputStream().flush(); if you want to use HttpServletResponse. Otherwise, Tim's answer provides an easier way to do it.

zakaria amine
  • 3,412
  • 2
  • 20
  • 35
0

You can set the media type as: application/json;charset=UTF-8 by using:

HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON_UTF8);
F. Müller
  • 3,969
  • 8
  • 38
  • 49