Quel est le moyen le plus approprié et standard de définir le Content-Disposition=attachment
et le filename=xyz.Zip
à l’aide de Spring 3 FileSystemResource
?
L'action ressemble à:
@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);
}
Bien que le fichier soit un fichier Zip, le navigateur télécharge toujours le fichier, mais je voudrais mentionner explicitement le fichier en tant que pièce jointe et fournir également un nom de fichier qui n'a rien à voir avec le nom réel du fichier.
Il existe peut-être des solutions de contournement pour résoudre ce problème, mais je voudrais savoir comment printemps et FileSystemResource
convient pour atteindre cet objectif.
P.S. Le fichier utilisé ici est un fichier temporaire, destiné à être supprimé lorsque la JVM existe.
@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"));
}
En plus de la réponse acceptée, Spring a la classe ContentDisposition spécifique à cette fin. Je crois qu'il s'agit de la désinfection du nom de fichier.
ContentDisposition contentDisposition = ContentDisposition.builder("inline")
.filename("Filename")
.build();
HttpHeaders headers = new HttpHeaders();
headers.setContentDisposition(contentDisposition);
Voici une approche alternative pour Spring 4. Notez que cet exemple n'utilise clairement pas les bonnes pratiques en matière d'accès au système de fichiers. Il s'agit simplement de montrer comment certaines propriétés peuvent être définies de manière déclarative.
@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);
}