2016-11-28 5 views
0

Ich arbeite an Spring Boot-Anwendung, und ich habe Probleme beim Herunterladen großer Dateien. Nämlich, wenn ich auf den Download-Link auf der Client-Seite klicke, dauert es lange, bis der Browser-Download-Dialog erscheint. Bei kleinen Dateien erscheint es sofort, bei großen Dateien dauert es bis zu 30 Sekunden.Download große Dateien ohne Blockierung

Das lässt mich denken, dass mein Controller blockiert, bis der Dateiinhalt vollständig in den Antwort-Ausgabestream geschrieben wurde, bevor er an den Client gesendet wird. Ich habe verschiedene Optionen ausprobiert, damit die Antwort sofort gesendet wird, aber immer noch keine Ergebnisse haben. Das ist, was ich habe, so weit:

@RequestMapping(method = RequestMethod.GET, value = "/content/file/download") 
public ResponseEntity<InputStreamResource> downloadFile(@RequestParam(name = "path") String path, HttpServletRequest request) 
      throws IOException, NotFoundException, BadRequestException, InternalServerErrorException{ 
    getApplicationId(request); 
    String orgId = getOrganizationId(request); 
    LOGGER.debug("Downloading for path {}", path); 

    try{ 
     Session session = getCurrentSession(request); 
     FileStorageService service = new JCRFileStorageService(session); 
     ProtonItem item = service.getItem(path, orgId); 

     InputStream is = service.getFileDownloadStream(path, orgId); 
     InputStreamResource resource = new InputStreamResource(is); 

     HttpHeaders headers = new HttpHeaders(); 
     headers.setContentLength(item.getMetadata().getMetadata(ProtonBaseConstants.META_FILE_SIZE, Long.class)); 
     headers.set(HttpHeaders.CONTENT_TYPE, item.getMetadata().getMetadata(ProtonBaseConstants.META_MIME_TYPE, String.class)); 
     headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + item.getName()); 

     return ResponseEntity.ok().headers(headers).body(resource); 


    } catch(ProtonRepoException ex){ 
     throw ProtonExceptionMapper.processException(ex); 
    } 
} 

Verschiedene Quellen Online-Punkt, dass dies ausreichend sein sollte, Download sofort zu haben, beginnen, aber es funktioniert nicht. Ich versuchte mit IOUtils.copy(), direktes Kopieren von Eingang zu Ausgangsstrom, aber nichts scheint zu arbeiten.

Gibt es etwas, das mir fehlt? Vielleicht eine Spring Boot-Konfiguration oder irgendetwas anderes?

+1

Und was macht 'service.getFileDownloadStream'? ... Etwas In-Memory vielleicht als ein Byte []' lesen? Anstatt zu raten, können Sie Ihrer Anwendung Messwerte hinzufügen, um herauszufinden, was lange dauert. –

+0

Nein, diese Methode gibt 'InputStream' nur an die zugrunde liegende Datei zurück. Ich habe das überprüft und es ist nicht das Problem, es dauert nur ein paar Millisekunden. – vdjurovic

+0

Wie erstellen Sie große Dateien? B. SQL-Resultset-Mapping auf Objekt und dann auf Datei, wenn dies der Fall ist, dann überspringen Sie das Mapping und streamen direkt von der Ergebnismenge. – Ibrahim

Antwort

-1

meine eigene Frage zu beantworten ... Es stellt sich heraus, dass Problem überhaupt nicht auf Server-Seite, sondern vielmehr auf dem Client. Ich testete mit zwei verschiedenen Clients, und Download funktioniert wie erwartet, dh. beginnt sofort.

Das ursprüngliche Problem kommt von Angular-Client, den wir verwenden, und hat nichts mit Serverseite zu tun.

Entschuldigung für die Verschwendung aller Zeit. Vielen Dank für die Hilfe, Jungs.

+0

Ich verstehe diese Antwort nicht. Welche Kunden haben Sie getestet? Dies scheint eher ein Kommentar als eine Antwort zu sein. –

+0

Wir verwenden Angular App als Frontend. Es wird eine Datei heruntergeladen, indem eine GET-Anforderung an den Server gesendet wird. Das Problem, das ist nicht das gleiche wie Browser GET, dh. Das Browser-Download-Fenster wird erst angezeigt, wenn die Datei vollständig heruntergeladen wurde. – vdjurovic