2013-05-17 7 views
10

Jaki jest najbardziej odpowiedni i standardowy sposób ustawiania Content-Disposition=attachment i filename=xyz.zip przy użyciu Spring 3 FileSystemResource?Jak ustawić "Content-Disposition" i "Filename" podczas korzystania z FileSystemResource, aby wymusić pobranie pliku?

Akcja wygląda następująco:

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

Chociaż jest to plik zip więc przeglądarka zawsze pobiera plik, ale chciałbym, aby wyraźnie wspomnieć plik jako załącznik, a także nazwę pliku, który ma nie ma nic wspólnego z rzeczywistą nazwą pliku.

Może istnieć obejście tego problemu, ale chciałbym poznać właściwą metodę Spring i FileSystemResource, aby osiągnąć ten cel.

P.S. Używany tutaj plik jest plikiem tymczasowym oznaczonym do usunięcia, gdy istnieje JVM.

Odpowiedz

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

Należy jednak zauważyć, że ulegnie to zerwaniu, jeśli nazwa pliku zawiera znaki "token", takie jak białe znaki, znaki spoza zestawu ASCII i niektóre ograniczniki. –

+2

krótka odpowiedź 'response.setHeader (" Content-Disposition "," attachment; filename = "+ YOUR_FILE_NAME);' –

+0

Unikaj odpowiedzi tylko do kodu. Podaj objaśnienia dotyczące fragmentu kodu! – 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

co dokładnie oznacza zwrócenie tej metody ?, co to jest myService? – user3809938

+0

@ user3809938 Konstruktor dla FileSystemResource może zająć ścieżkę 'File' lub' String' – Phas1c

1

Oto alternatywne podejście do wiosennego 4. Należy pamiętać, że w tym przykładzie wyraźnie nie korzysta z dobrych praktyk w zakresie dostępu do systemu plików, jest to po prostu pokazują, jak niektóre właściwości można ustawić deklaratywnie.

@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); 
} 
Powiązane problemy