2013-05-17 21 views
10

Qual è il modo più appropriato e standard per impostare e filename=xyz.zip utilizzando Spring 3 FileSystemResource?Come impostare "Content-Disposition" e "Filename" quando si utilizza FileSystemResource per forzare un file di download del file?

L'azione si presenta come:

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

Anche se il file è un file zip in modo che il browser scarica sempre il file, ma vorrei citare esplicitamente il file come allegato, e anche fornire un nome di file che ha niente a che fare con il nome reale dei file.

Potrebbero esserci soluzioni alternative per questo problema, ma mi piacerebbe conoscere il modo corretto Spring e FileSystemResource per raggiungere questo obiettivo.

P.S. Il file che viene utilizzato qui è un file temporaneo, contrassegnato per l'eliminazione quando esiste la JVM.

risposta

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

Ma si noti che questo si interromperà se il nome file contiene caratteri non "token", come spazi bianchi, non ASCII e determinati delimitatori. –

+2

risposta breve 'response.setHeader (" Content-Disposition "," attachment; filename = "+ YOUR_FILE_NAME);' –

+0

Evita risposte di solo codice. Fornisci alcune spiegazioni sullo snippet! – Manu343726

7
@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

cosa restituisce esattamente questo metodo? Che cos'è myService? – user3809938

+0

@ user3809938 il costruttore per FileSystemResource può prendere un 'File' o' String' per il percorso – Phas1c

1

Ecco un approccio alternativo per la primavera 4. Si noti che questo esempio chiaramente non fa uso di buone pratiche in materia di accesso del file system, questo è solo per dimostrare come alcune proprietà possono essere impostate in modo dichiarativo.

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