简体   繁体   English

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

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

What is the most appropriate, and standard, way to set the Content-Disposition=attachment and filename=xyz.zip using Spring 3 FileSystemResource ? 使用Spring 3 FileSystemResource设置Content-Disposition=attachmentfilename=xyz.zip的最合适,最标准的方法是什么?

The action looks like : 该动作如下:

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

Although the file is a zip file so the browser always downloads the file, but I would like to explicitly mention the file as attachment, and also provide a filename that has nothing to do with the files actual name. 虽然该文件是一个zip文件,因此浏览器总是下载该文件,但我想明确提到该文件为附件,并提供与文件实际名称无关的文件名。

There might be workarounds for this problem, but I would like to know the proper Spring and FileSystemResource way to achieve this goal. 这个问题可能有解决方法,但我想知道正确的Spring和FileSystemResource方法来实现这个目标。

PS The file that is being used here is a temporary file, marked for deletion when the JVM exists. PS此处使用的文件是临时文件,在JVM存在时标记为删除。

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

In addition to the accepted answer, Spring has the class ContentDisposition specific for this purpose. 除了接受的答案之外,Spring还有针对此目的的ContentDisposition类。 I believe it deals with the file name sanitization. 我相信它处理文件名清理。

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

      HttpHeaders headers = new HttpHeaders();
      headers.setContentDisposition(contentDisposition);

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 未在文件下载中设置Content-Disposition标头 - Content-Disposition header is not being set on a file download 如果Java将响应发送为“ content-disposition”,“ attachment; filename = FileEName.xls”,则如何通过ajax在现有窗口中下载文件 - How to download file in the existing window through ajax if the java is sending response as “content-disposition”, “attachment;filename=FileEName.xls” 如何在Content-Disposition标头中设置包含空格的文件名 - How to set filename containing spaces in Content-Disposition header 使用ANGULARJS从Jersey rest api调用下载/保存文件。 文件附带响应,内容为“ Content-Disposition” - File download/save from a Jersey rest api call using ANGULARJS . file is attached with response as “Content-Disposition” 使用内容处置下载文件时出现问题 - Having issue while downloading a file using content-disposition 如何在Java中为大文件名正确设置HTTP Content-Disposition? - How do I correctly set the HTTP Content-Disposition for large file names in Java? 如何在 java Google App Engine 中为 static 文件将内容处置设置为内联 - How to set content-disposition to inline for static file(s) in java Google App Engine 如何从Java中的Content-Disposition获取文件? - How to get a file from Content-Disposition in java? AngularJS 标题中的“Content-Disposition”和文件名 - "Content-Disposition" and file name in headers with AngularJS 正在使用Content-Disposition标头保存文件 - File is being saved with Content-Disposition header
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM