我有一個須要從網站下載PDF的要求。 PDF須要在代碼中生成,我認爲這將是freemarker和iText等PDF生成框架的結合。 還有更好的方法嗎? html
可是,個人主要問題是如何容許用戶經過Spring Controller下載文件? java
經過使用Spring的ResourceHttpMessageConverter中的內置支持,我可以簡化這一過程。 若是能夠肯定mime類型,則將設置content-length和content-type spring
@RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET) @ResponseBody public FileSystemResource getFile(@PathVariable("file_name") String fileName) { return new FileSystemResource(myService.getFileFor(fileName)); }
在Spring 3.0中,您可使用HttpEntity
返回對象。 若是使用此選項,則您的控制器不須要HttpServletResponse
對象,所以測試起來更容易。 除此以外,這個答案相對於Infeligo之一 。 api
若是您的pdf框架的返回值是一個字節數組(請參閱個人答案的第二部分以獲取其餘返回值) : 數組
@RequestMapping(value = "/files/{fileName}", method = RequestMethod.GET) public HttpEntity<byte[]> createPdf( @PathVariable("fileName") String fileName) throws IOException { byte[] documentBody = this.pdfFramework.createPdf(filename); HttpHeaders header = new HttpHeaders(); header.setContentType(MediaType.APPLICATION_PDF); header.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName.replace(" ", "_")); header.setContentLength(documentBody.length); return new HttpEntity<byte[]>(documentBody, header); }
若是您的PDF Framework的返回類型( documentBbody
)還不是字節數組 (而且也沒有ByteArrayInputStream
),那麼明智的作法是不要首先使其成爲字節數組。 相反,最好使用: session
InputStreamResource
, PathResource
(從Spring 4.0開始)或 FileSystemResource
, FileSystemResource
示例: app
@RequestMapping(value = "/files/{fileName}", method = RequestMethod.GET) public HttpEntity<byte[]> createPdf( @PathVariable("fileName") String fileName) throws IOException { File document = this.pdfFramework.createPdf(filename); HttpHeaders header = new HttpHeaders(); header.setContentType(MediaType.APPLICATION_PDF); header.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName.replace(" ", "_")); header.setContentLength(document.length()); return new HttpEntity<byte[]>(new FileSystemResource(document), header); }
在單擊jsp上的連接時,該代碼能夠很好地從spring控制器自動下載文件。 框架
@RequestMapping(value="/downloadLogFile") public void getLogFile(HttpSession session,HttpServletResponse response) throws Exception { try { String filePathToBeServed = //complete file name with path; File fileToDownload = new File(filePathToBeServed); InputStream inputStream = new FileInputStream(fileToDownload); response.setContentType("application/force-download"); response.setHeader("Content-Disposition", "attachment; filename="+fileName+".txt"); IOUtils.copy(inputStream, response.getOutputStream()); response.flushBuffer(); inputStream.close(); } catch (Exception e){ LOGGER.debug("Request could not be completed at this moment. Please try again."); e.printStackTrace(); } }
若是你: electron
byte[]
; InputStream
發送/下載它; @ControllerAdvice
爲您拾取異常。 下面的代碼是您須要的: jsp
@RequestMapping(value = "/stuff/{stuffId}", method = RequestMethod.GET) public ResponseEntity<InputStreamResource> downloadStuff(@PathVariable int stuffId) throws IOException { String fullPath = stuffService.figureOutFileNameFor(stuffId); File file = new File(fullPath); HttpHeaders respHeaders = new HttpHeaders(); respHeaders.setContentType("application/pdf"); respHeaders.setContentLength(12345678); respHeaders.setContentDispositionFormData("attachment", "fileNameIwant.pdf"); InputStreamResource isr = new InputStreamResource(new FileInputStream(file)); return new ResponseEntity<InputStreamResource>(isr, respHeaders, HttpStatus.OK); }
還要注意,爲避免讀取整個文件只是爲了計算其長度,最好事先存儲它。 確保檢查了InputStreamResource
的文檔。
下面的代碼爲我工做,以生成和下載文本文件。
@RequestMapping(value = "/download", method = RequestMethod.GET) public ResponseEntity<byte[]> getDownloadData() throws Exception { String regData = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; byte[] output = regData.getBytes(); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set("charset", "utf-8"); responseHeaders.setContentType(MediaType.valueOf("text/html")); responseHeaders.setContentLength(output.length); responseHeaders.set("Content-disposition", "attachment; filename=filename.txt"); return new ResponseEntity<byte[]>(output, responseHeaders, HttpStatus.OK); }