使用FileSystemResource强制文件下载文件时如何设置’Content-Disposition’和’Filename’?

使用Spring 3 FileSystemResource设置Content-Disposition=attachmentfilename=xyz.zip的最合适,最标准的方法是什么?

该动作如下:

 @ResponseBody @RequestMapping(value = "/action/{abcd}/{efgh}", method = RequestMethod.GET, produces = "application/zip") @PreAuthorize("@authorizationService.authorizeMethod()") public FileSystemResource doAction(@PathVariable String abcd, @PathVariable String efgh) { File zipFile = service.getFile(abcd, efgh); return new FileSystemResource(zipFile); } 

虽然该文件是一个zip文件,因此浏览器总是下载该文件,但我想明确提到该文件作为附件,并提供与文件实际名称无关的文件名。

这个问题可能有解决方法,但我想知道正确的Spring和FileSystemResource方法来实现这个目标。

PS此处使用的文件是临时文件,在JVM存在时标记为删除。

 @RequestMapping(value = "/action/{abcd}/{efgh}", method = RequestMethod.GET) @PreAuthorize("@authorizationService.authorizeMethod(#id)") public HttpEntity doAction(@PathVariable ObjectType obj, @PathVariable Date date, HttpServletResponse response) throws IOException { ZipFileType zipFile = service.getFile(obj1.getId(), date); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); response.setHeader("Content-Disposition", "attachment; filename=" + zipFile.getFileName()); return new HttpEntity(zipFile.getByteArray(), headers); } 
  @RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET) @ResponseBody public FileSystemResource getFile(@PathVariable("file_name") String fileName,HttpServletResponse response) { response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=somefile.pdf"); return new FileSystemResource(new File("file full path")); } 

这是Spring 4的另一种方法。请注意,此示例显然没有使用有关文件系统访问的良好实践,这只是为了演示如何以声明方式设置某些属性。

 @RequestMapping(value = "/{resourceIdentifier}", method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) // @ResponseBody // Needed for @Controller but not for @RestController. public ResponseEntity download(@PathVariable(name = "resourceIdentifier") final String filename) throws Exception { final String resourceName = filename + ".dat"; final File iFile = new File("/some/folder", resourceName); final long resourceLength = iFile.length(); final long lastModified = iFile.lastModified(); final InputStream resource = new FileInputStream(iFile); return ResponseEntity.ok() .header("Content-Disposition", "attachment; filename=" + resourceName) .contentLength(resourceLength) .lastModified(lastModified) .contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE) .body(resource); } 

对两个给定的答案做了一些改动,我在我的项目中最好的两个,我需要从数据库中提取图像作为blob,然后将其提供给客户端:

 @GetMapping("/images/{imageId:.+}") @ResponseBody public ResponseEntity serveFile(@PathVariable @Valid String imageId,HttpServletResponse response) { ImageEntity singleImageInfo=db.storage.StorageService.getImage(imageId); if(singleImageInfo==null) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); } Blob image=singleImageInfo.getImage(); try { String filename= UsersExtra.GenerateSession()+"xxyy"+singleImageInfo.getImage1Ext().trim(); byte [] array = image.getBytes( 1, ( int ) image.length() ); File file = File.createTempFile(UsersExtra.GenerateSession()+"xxyy", singleImageInfo.getImage1Ext().trim(), new File(".")); FileOutputStream out = new FileOutputStream( file ); out.write( array ); out.close(); FileSystemResource testing=new FileSystemResource(file); String mimeType = "image/"+singleImageInfo.getImage1Ext().trim().toLowerCase().replace(".", ""); response.setContentType(mimeType); String headerKey = "Content-Disposition"; String headerValue = String.format("attachment; filename=\"%s\"", filename); response.setHeader(headerKey, headerValue); // return new FileSystemResource(file); return ResponseEntity.status(HttpStatus.OK).body( new FileSystemResource(file)); }catch(Exception e) { System.out.println(e.getMessage()); } return null; } 

在Kumar的代码中使用ResponseEntity将帮助您使用正确的响应代码进行响应。 注意:从此链接引用从blob到文件的转换:从Java中的blob内容创建文件的代码段