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

后端 未结 5 630
囚心锁ツ
囚心锁ツ 2020-12-13 17:52

What is the most appropriate, and standard, way to set the Content-Disposition=attachment and filename=xyz.zip using Spring 3 FileSystemResou

相关标签:
5条回答
  • 2020-12-13 18:16

    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);
    
    0 讨论(0)
  • 2020-12-13 18:16
     @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")); 
        }
    
    0 讨论(0)
  • 2020-12-13 18:21
    @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);
    }
    
    0 讨论(0)
  • 2020-12-13 18:22

    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

    0 讨论(0)
  • 2020-12-13 18:36

    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);
    }
    
    0 讨论(0)
提交回复
热议问题