web-dev-qa-db-fra.com

Comment définir 'Content-Disposition' et 'Nom de fichier' lors de l'utilisation de FileSystemResource pour forcer le téléchargement d'un fichier?

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.

18
Hassan Jamil
@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);
}
22
Hassan Jamil
 @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")); 
    }
11
Kumar

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);
3
Jefferson Lima

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);
}
3
vallismortis