How to set 'Content-Disposition' and 'Filename' when using FileSystemResource to force a file download file?

我与影子孤独终老i 提交于 2019-12-02 18:57:40
@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);
}

In addition to the accepted answer, Spring has the class ContentDisposition specific for this purpose. I believe it deals with the file name sanitization.

      ContentDisposition contentDisposition = ContentDisposition.builder("inline")
          .filename("Filename")
          .build();

      HttpHeaders headers = new HttpHeaders();
      headers.setContentDisposition(contentDisposition);
 @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")); 
    }

Here is an alternative approach for Spring 4. Note that this example clearly does not use good practices regarding filesystem access, this is just to demonstrate how some properties can be set declaratively.

@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);
}

Made few changes to both given answers and I ended up with the best of both in my project where I needed to extract an image from the database as a blob and then serve it to the clients :

@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;
}

Using a ResponseEntity in Kumar's code will help you respond with the correct Response code. Note: converting from a blob to a file is quoted from this link: Snippet to create a file from the contents of a blob in Java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!