2017-01-01 95 views
1

我跟着this后的功能:客户端可以下载一个文件(即csv,pdf和zip)截至目前。Spring REST/Swagger/Postman - 损坏/空白文件正在下载

但是,无论是我得到的PDF是空白的或尝试使用zip文件时,它已经损坏。只有CSV工作正常

我检查了标题,一切似乎按照标准。我甚至不使用“application/octet-stream”,使用pdf的“application/pdf”,使用csv的“application/csv”和使用zip的“application/zip”,以避免客户端出现问题。我正在使用swagger 2.4来测试我的apis。这是我的代码。

@CrossOrigin 
@Controller 
public class ReportRestController { 


@Autowired 
ReportService reportService; 

@Value("${report.temp.directory}") // used for storing file in local 
private String reportLocation; 

@ApiImplicitParams({ 
     @ApiImplicitParam(name = "Authorization", value = "Authorization", required = true, dataType = "string", paramType = "header"), 
     @ApiImplicitParam(name = "Auth-Provider", value = "Auth-Provider", required = true, dataType = "string", paramType = "header"),}) 
@RequestMapping(value = "/report/{type}/{format}", method = RequestMethod.POST) 
public void getList(@RequestHeader(value = "UserId", required = false) Long userId, 
     @RequestHeader(value = "TeamId", required = false) Long teamId, 
     @RequestHeader(value = "CustomerId", required = true) Long customerId, 
     @PathVariable("type") String type, @PathVariable("format") String formate, 
     @RequestBody ReportRequestObj reportobj, HttpServletResponse response) { 

    String filename = reportService.getReport(customerId, userId, teamId, type, formate, reportobj); 
    Path pathfile = Paths.get(reportLocation, filename); 
    File file = pathfile.toFile(); 
    if (file.exists()) { 
     String fileExtension = FilenameUtils.getExtension(filename); 
     if(CommonConstants.CSV.equals(fileExtension)){ 
      response.setContentType("application/csv"); 
     }else if(CommonConstants.PDF.equals(fileExtension)){ 
      response.setContentType("application/pdf"); 
     }else if(CommonConstants.ZIP.equals(fileExtension)){ 
      response.setContentType("application/zip"); 
     } 
     response.addHeader("Content-Disposition", "attachment; filename=" + filename); 
     response.setContentLength((int) file.length()); 
     response.setHeader("Content-Transfer-Encoding", "binary"); 
     try(FileInputStream fileInputStream = new FileInputStream(file)) { 
      IOUtils.copy(fileInputStream,response.getOutputStream()); 
      response.getOutputStream().flush(); 
      //response.flushBuffer(); 
     } catch (IOException ex) { 
      log.error("Error while sending the file:{} for customerId:{} ,userId:{}", 
        file.getPath(), customerId, userId); 
     } 
    } 
} 

请让我知道我在做什么错误或丢失?

编辑1:我附上响应头我:

{ 
"date": "Sun, 01 Jan 2017 19:11:13 GMT", 
"x-content-type-options": "nosniff", 
"access-control-max-age": "3600", 
"content-disposition": "attachment; filename=localhost-blob-abcd.pdf", 
"content-length": "172962", 
"x-xss-protection": "1; mode=block", 
"x-application-context": "report-server:8095", 
"pragma": "no-cache", 
"server": "Apache-Coyote/1.1", 
"x-frame-options": "DENY", 
"access-control-allow-methods": "POST, PUT, GET, OPTIONS, DELETE", 
"content-type": "application/pdf;charset=UTF-8", 
"access-control-allow-origin": "*", 
"cache-control": "no-cache, no-store, max-age=0, must-revalidate, no-cache", 
"access-control-allow-headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Auth-Provider, UserId, TeamId, Lang, CustomerId", 
"expires": "0" 
} 

回答

2

好吧,此代码的工作对我来说:

package com.example; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 

import javax.servlet.http.HttpServletResponse; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.core.io.InputStreamResource; 
import org.springframework.http.CacheControl; 
import org.springframework.http.MediaType; 
import org.springframework.http.ResponseEntity; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 

@SpringBootApplication 
public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 

    @Controller 
    public class DownloadController { 

     @RequestMapping("/download") 
     public ResponseEntity<InputStreamResource> download() throws FileNotFoundException { 
      final File file = new File("file.pdf"); 
      return ResponseEntity.ok() 
        .contentLength(file.length()) 
        .contentType(MediaType.APPLICATION_PDF) 
        .cacheControl(CacheControl.noCache()) 
        .header("Content-Disposition", "attachment; filename=" + file.getName()) 
        .body(new InputStreamResource(new FileInputStream(file))); 
     } 
    } 
} 

没有什么具体到春季启动,您可以在使用用普通的Spring MVC。

也许这是一个像这样的Swagger问题:File download via content-disposition header corrupts file,而不是服务器端的问题。您是否尝试过使用其他工具测试此API调用?例如curl永远不会让我失望。

+0

感谢您的快速响应。但是回应是一样的 - 黑色PDF和损坏的zip文件。 –

+0

@ balboa_21提供使用ResponseEntity API实现缓冲文件以响应复制的示例代码。 –

+0

嗨@yanys,仍是同样的问题。空白的pdf + zip文件已损坏。只有csv工作正常。当然,我会改变标题,我不知道还有什么要放,所以我写了Spring Boot。谢谢。顺便说一下,我正在使用招摇来进行测试。 –