it-swarm.com.de

Wie können Sie 'Content-Disposition' und 'Filename' festlegen, wenn Sie FileSystemResource verwenden, um eine Datei-Download-Datei zu erzwingen?

Was ist der geeignetste und standardisierte Weg, um Content-Disposition=attachment und filename=xyz.Zip mit Spring 3 FileSystemResource einzustellen?

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, lädt der Browser die Datei immer herunter. Ich möchte jedoch ausdrücklich die Datei als Anhang angeben und auch einen Dateinamen angeben, der nichts mit dem tatsächlichen Namen der Dateien zu tun hat.

Möglicherweise gibt es Abhilfemaßnahmen für dieses Problem, aber ich würde gerne wissen, wie Spring und FileSystemResource geeignet sind, um dieses Ziel zu erreichen.

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

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

Spring hat zusätzlich zu der akzeptierten Antwort die für diesen Zweck spezifische Klasse ContentDisposition . Ich glaube, es handelt sich um die Bereinigung des Dateinamens.

      ContentDisposition contentDisposition = ContentDisposition.builder("inline")
          .filename("Filename")
          .build();

      HttpHeaders headers = new HttpHeaders();
      headers.setContentDisposition(contentDisposition);
3
Jefferson Lima

Hier ist ein alternativer Ansatz für Spring 4. Beachten Sie, dass dieses Beispiel eindeutig keine bewährten Methoden für den Dateisystemzugriff verwendet. Dies soll nur 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);
}
3
vallismortis

An beiden Antworten wurden nur wenige Änderungen vorgenommen, und ich erhielt das Beste aus beiden Projekten, bei dem ich ein Bild aus der Datenbank als Blob extrahieren und es den Kunden zur Verfügung stellen musste:

@GetMapping("/images/{imageId:.+}")
@ResponseBody
public ResponseEntity<FileSystemResource>  serveFile(@PathVariable @Valid String imageId,HttpServletResponse response)
{       
    ImageEntity singleImageInfo=db.storage.StorageService.getImage(imageId);
    if(singleImageInfo==null)
    {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
    }
    Blob image=singleImageInfo.getImage();
    try {           
        String filename= UsersExtra.GenerateSession()+"xxyy"+singleImageInfo.getImage1Ext().trim();

    byte [] array = image.getBytes( 1, ( int ) image.length() );
    File file = File.createTempFile(UsersExtra.GenerateSession()+"xxyy", singleImageInfo.getImage1Ext().trim(), new File("."));
    FileOutputStream out = new FileOutputStream( file );
    out.write( array );
    out.close();
    FileSystemResource testing=new FileSystemResource(file);

    String mimeType = "image/"+singleImageInfo.getImage1Ext().trim().toLowerCase().replace(".", "");
      response.setContentType(mimeType);    

        String headerKey = "Content-Disposition";
       String headerValue = String.format("attachment; filename=\"%s\"", filename);
       response.setHeader(headerKey, headerValue);
      // return new FileSystemResource(file); 
       return ResponseEntity.status(HttpStatus.OK).body( new FileSystemResource(file));
    }catch(Exception e)
    {
        System.out.println(e.getMessage());
    }
    return null;
}

Die Verwendung einer ResponseEntity im Kumar-Code hilft Ihnen, mit dem korrekten Antwortcode zu antworten .. Hinweis: Das Konvertieren von einem Blob in eine Datei erfolgt über diesen Link: Snippet zum Erstellen einer Datei aus dem Inhalt eines Blobs in Java

0
Fahad Alkamli