在Spring REST服务中下载zip文件的问题

时间:2017-06-24 03:27:37

标签: spring rest spring-boot download zip

我的API如下:

@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);

休息控制器:

 @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();
    }

}

回应:

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

问题:

我想将zip文件作为附件下载,但响应如上。

注意:  我尝试了Rest Download Endpoints上解释的所有下载方法,但没有一个成功。我还添加了

  

produce = MediaType.APPLICATION_OCTET_STREAM_VALUE

到API定义但又没有成功。

所以,如果有人能帮助我找到真正的解决方案,我将非常感激。

3 个答案:

答案 0 :(得分:1)

我有同样的问题。正在将Content-Type更改为MediaType.APPLICATION_PDF_VALUE触发下载操作。但是,默认情况下,“另存为”对话框将文件扩展名显示为.pdf

使用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");
        }

如果您使用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);

答案 1 :(得分:0)

您只需在控制器中返回ResponseEntity<byte[]>即可。将Content-Type和Content-Disposition标头添加到您的响应中,以便正确打开。

    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);
   }

答案 2 :(得分:0)

根据HttpServletResponse doc:调用flush()提交响应。如果你想使用HttpServletResponse,我想你需要调用fit。否则,蒂姆的回答提供了一种更简单的方法。