2013-05-17 7 views
10

Was ist die geeignetste und Standardmethode, um die Content-Disposition=attachment und filename=xyz.zip unter Verwendung von Spring 3 FileSystemResource einzustellen?Wie wird 'Content-Disposition' und 'Dateiname' festgelegt, wenn FileSystemResource verwendet wird, um eine Dateidownloaddatei zu erzwingen?

Die Aktion sieht so aus:

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

Obwohl die Datei eine Zip-Datei ist damit der Browser immer die Datei herunterlädt, aber ich möchte ausdrücklich die Datei als Anhang erwähnen, und auch einen Dateinamen bereitzustellen, hat nichts mit dem tatsächlichen Namen der Dateien zu tun.

Es könnte Workarounds für dieses Problem geben, aber ich würde gerne den richtigen Frühling kennen und FileSystemResource Weg, um dieses Ziel zu erreichen.

P.S. Die Datei, die hier verwendet wird, ist eine temporäre Datei, die zum Löschen markiert wird, wenn die JVM existiert.

Antwort

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

Aber beachten Sie, dass dies bricht, wenn der Dateiname nicht "Token" -Zeichen wie Leerzeichen, Nicht-ASCII und bestimmte Trennzeichen enthält. –

+2

kurze Antwort 'response.setHeader (" Content-Disposition "," Anhang; Dateiname = "+ YOUR_FILE_NAME);' –

+0

Vermeiden Sie Code-Only-Antworten. Geben Sie einige Erläuterungen zum Snippet an! – 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

Was genau ist diese Methode zurück? Was ist myService? – user3809938

+0

@ user3809938 Der Konstruktor für FileSystemResource kann eine 'File' oder' String' für den Pfad nehmen – Phas1c

1

Hier ist ein alternativer Ansatz für den Frühling 4. Beachten Sie, dass dieses Beispiel eindeutig nicht gut Praktiken nicht verwendet in Bezug auf Dateisystemzugriff, ist dies nur zu zeigen, wie einige Eigenschaften deklarativ festgelegt werden können.

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