How to set 'Content-Disposition' and 'Filename' when using FileSystemResource to force a file download file?
使用Spring 3
动作看起来像:
1 2 3 4 5 6 7 8 9 | @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和
附言 此处使用的文件是一个临时文件,当JVM存在时,标记为删除。
1 2 3 4 5 6 7 8 9 10 11 | @RequestMapping(value ="/action/{abcd}/{efgh}", method = RequestMethod.GET) @PreAuthorize("@authorizationService.authorizeMethod(#id)") public HttpEntity<byte[]> 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<byte[]>(zipFile.getByteArray(), headers); } |
除了可接受的答案外,Spring还具有为此目的而特定的类ContentDisposition。 我相信它可以处理文件名清理。
1 2 3 4 5 6 | ContentDisposition contentDisposition = ContentDisposition.builder("inline") .filename("Filename") .build(); HttpHeaders headers = new HttpHeaders(); headers.setContentDisposition(contentDisposition); |
1 2 3 4 5 6 7 | @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的另一种方法。请注意,此示例显然未使用有关文件系统访问的良好做法,这只是为了演示如何声明性地设置某些属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @RequestMapping(value ="/{resourceIdentifier}", method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) // @ResponseBody // Needed for @Controller but not for @RestController. public ResponseEntity<InputStreamResource> 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,然后将其提供给客户:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | @GetMapping("/images/{imageId:.+}") @ResponseBody public ResponseEntity<FileSystemResource> 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将帮助您使用正确的Response代码进行响应。
注意:此链接引用了从Blob到文件的转换:
通过Java中的Blob内容创建文件的代码段