从弹簧控制器下载文件

问题

我有一个要求,我需要从网站上下载PDF。 PDF需要在代码中生成,我认为这将是freemarker和像iText这样的PDF生成框架的组合。有更好的方法吗?

但是,我的主要问题是如何允许用户通过Spring Controller下载文件?


#1 热门回答(335 赞)

@RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
public void getFile(
    @PathVariable("file_name") String fileName, 
    HttpServletResponse response) {
    try {
      // get your file as InputStream
      InputStream is = ...;
      // copy it to response's OutputStream
      org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
      response.flushBuffer();
    } catch (IOException ex) {
      log.info("Error writing file to output stream. Filename was '{}'", fileName, ex);
      throw new RuntimeException("IOError writing file to output stream");
    }

}

一般来说,当你有response.getOutputStream()时,你可以在那里写任何东西。你可以将此输出流作为将生成的PDF放入生成器的位置。此外,如果你知道要发送的文件类型,则可以进行设置

response.setContentType("application/pdf");

#2 热门回答(265 赞)

通过使用Spring的内置支持和ResourceHttpMessageConverter,我能够对此进行流式处理。如果可以确定mime类型,这将设置content-length和content-type

@RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
@ResponseBody
public FileSystemResource getFile(@PathVariable("file_name") String fileName) {
    return new FileSystemResource(myService.getFileFor(fileName)); 
}

#3 热门回答(69 赞)

你应该能够直接在响应上写入文件。就像是

response.setContentType("application/pdf");      
response.setHeader("Content-Disposition", "attachment; filename=\"somefile.pdf\"");

然后将文件写为二进制流onresponse.getOutputStream()。记得最后做response.flush(),应该这样做。