[英]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=attachment
和filename=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.