Angular doesn't download a file from a stream ( StreamingResponseBody )












3














I'm using angular to download big files, for the backend I'm using spring boot, here's the code of the end point:



@RequestMapping(value = "/download", method = RequestMethod.GET)
public StreamingResponseBody download(@PathVariable String path) throws IOException {

final InputStream file =azureDataLakeStoreService.readFile(path);
return (os) -> {
readAndWrite(file , os);
};
}

private void readAndWrite(final InputStream is, OutputStream os)
throws IOException {
byte data = new byte[2048];
int read = 0;
while ((read = is.read(data)) >= 0) {
System.out.println("appending to file");
os.write(data, 0, read);
}
os.flush();
}


When I try to get the file using curl it works, and I can see the file being downloaded and it's size increasing:



curl -H "Authorization: Bearer <MyToken>" http://localhost:9001/rest/api/analyses/download --output test.zip


However, when I try to download a file using angular it doesn't work, even though the request is successful, and I can see in the logs the text "appending to file" showing multiple times, but nothing is downloading on the browser, here's my code:



this.http.get(url, { headers: headers, responseType: 'blob', observe: 'response' })
.subscribe(response => {
const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const parts: string = contentDispositionHeader.split(';');
const filename = parts[1].split('=')[1];
const blob = new Blob([response.body], {
type: 'application/zip'
});
saveAs(blob, filename);
});


saveAs() belong to file-saver, btw the above code works when I try to download a file as a byte ( without streaming ).



All I can find in the internet is this code and it's using angularJs while I'm using angular 5, Can anybody point the problem! thanks.



UPDATE:



I can see that the file is being downloaded in the network tab of Google chrome, but I have no idea where the file is being saved.



enter image description here










share|improve this question
























  • What's the error on the console ?
    – Svg_af
    Nov 19 '18 at 11:28










  • There's no error nor a response even though the end point was called and file is being precessed in the backend, but nothing to the client which is quite strange!
    – Abdenaceur Lichiheb
    Nov 19 '18 at 11:29
















3














I'm using angular to download big files, for the backend I'm using spring boot, here's the code of the end point:



@RequestMapping(value = "/download", method = RequestMethod.GET)
public StreamingResponseBody download(@PathVariable String path) throws IOException {

final InputStream file =azureDataLakeStoreService.readFile(path);
return (os) -> {
readAndWrite(file , os);
};
}

private void readAndWrite(final InputStream is, OutputStream os)
throws IOException {
byte data = new byte[2048];
int read = 0;
while ((read = is.read(data)) >= 0) {
System.out.println("appending to file");
os.write(data, 0, read);
}
os.flush();
}


When I try to get the file using curl it works, and I can see the file being downloaded and it's size increasing:



curl -H "Authorization: Bearer <MyToken>" http://localhost:9001/rest/api/analyses/download --output test.zip


However, when I try to download a file using angular it doesn't work, even though the request is successful, and I can see in the logs the text "appending to file" showing multiple times, but nothing is downloading on the browser, here's my code:



this.http.get(url, { headers: headers, responseType: 'blob', observe: 'response' })
.subscribe(response => {
const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const parts: string = contentDispositionHeader.split(';');
const filename = parts[1].split('=')[1];
const blob = new Blob([response.body], {
type: 'application/zip'
});
saveAs(blob, filename);
});


saveAs() belong to file-saver, btw the above code works when I try to download a file as a byte ( without streaming ).



All I can find in the internet is this code and it's using angularJs while I'm using angular 5, Can anybody point the problem! thanks.



UPDATE:



I can see that the file is being downloaded in the network tab of Google chrome, but I have no idea where the file is being saved.



enter image description here










share|improve this question
























  • What's the error on the console ?
    – Svg_af
    Nov 19 '18 at 11:28










  • There's no error nor a response even though the end point was called and file is being precessed in the backend, but nothing to the client which is quite strange!
    – Abdenaceur Lichiheb
    Nov 19 '18 at 11:29














3












3








3







I'm using angular to download big files, for the backend I'm using spring boot, here's the code of the end point:



@RequestMapping(value = "/download", method = RequestMethod.GET)
public StreamingResponseBody download(@PathVariable String path) throws IOException {

final InputStream file =azureDataLakeStoreService.readFile(path);
return (os) -> {
readAndWrite(file , os);
};
}

private void readAndWrite(final InputStream is, OutputStream os)
throws IOException {
byte data = new byte[2048];
int read = 0;
while ((read = is.read(data)) >= 0) {
System.out.println("appending to file");
os.write(data, 0, read);
}
os.flush();
}


When I try to get the file using curl it works, and I can see the file being downloaded and it's size increasing:



curl -H "Authorization: Bearer <MyToken>" http://localhost:9001/rest/api/analyses/download --output test.zip


However, when I try to download a file using angular it doesn't work, even though the request is successful, and I can see in the logs the text "appending to file" showing multiple times, but nothing is downloading on the browser, here's my code:



this.http.get(url, { headers: headers, responseType: 'blob', observe: 'response' })
.subscribe(response => {
const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const parts: string = contentDispositionHeader.split(';');
const filename = parts[1].split('=')[1];
const blob = new Blob([response.body], {
type: 'application/zip'
});
saveAs(blob, filename);
});


saveAs() belong to file-saver, btw the above code works when I try to download a file as a byte ( without streaming ).



All I can find in the internet is this code and it's using angularJs while I'm using angular 5, Can anybody point the problem! thanks.



UPDATE:



I can see that the file is being downloaded in the network tab of Google chrome, but I have no idea where the file is being saved.



enter image description here










share|improve this question















I'm using angular to download big files, for the backend I'm using spring boot, here's the code of the end point:



@RequestMapping(value = "/download", method = RequestMethod.GET)
public StreamingResponseBody download(@PathVariable String path) throws IOException {

final InputStream file =azureDataLakeStoreService.readFile(path);
return (os) -> {
readAndWrite(file , os);
};
}

private void readAndWrite(final InputStream is, OutputStream os)
throws IOException {
byte data = new byte[2048];
int read = 0;
while ((read = is.read(data)) >= 0) {
System.out.println("appending to file");
os.write(data, 0, read);
}
os.flush();
}


When I try to get the file using curl it works, and I can see the file being downloaded and it's size increasing:



curl -H "Authorization: Bearer <MyToken>" http://localhost:9001/rest/api/analyses/download --output test.zip


However, when I try to download a file using angular it doesn't work, even though the request is successful, and I can see in the logs the text "appending to file" showing multiple times, but nothing is downloading on the browser, here's my code:



this.http.get(url, { headers: headers, responseType: 'blob', observe: 'response' })
.subscribe(response => {
const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const parts: string = contentDispositionHeader.split(';');
const filename = parts[1].split('=')[1];
const blob = new Blob([response.body], {
type: 'application/zip'
});
saveAs(blob, filename);
});


saveAs() belong to file-saver, btw the above code works when I try to download a file as a byte ( without streaming ).



All I can find in the internet is this code and it's using angularJs while I'm using angular 5, Can anybody point the problem! thanks.



UPDATE:



I can see that the file is being downloaded in the network tab of Google chrome, but I have no idea where the file is being saved.



enter image description here







angular download inputstream outputstream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 13:59

























asked Nov 19 '18 at 0:01









Abdenaceur Lichiheb

8912729




8912729












  • What's the error on the console ?
    – Svg_af
    Nov 19 '18 at 11:28










  • There's no error nor a response even though the end point was called and file is being precessed in the backend, but nothing to the client which is quite strange!
    – Abdenaceur Lichiheb
    Nov 19 '18 at 11:29


















  • What's the error on the console ?
    – Svg_af
    Nov 19 '18 at 11:28










  • There's no error nor a response even though the end point was called and file is being precessed in the backend, but nothing to the client which is quite strange!
    – Abdenaceur Lichiheb
    Nov 19 '18 at 11:29
















What's the error on the console ?
– Svg_af
Nov 19 '18 at 11:28




What's the error on the console ?
– Svg_af
Nov 19 '18 at 11:28












There's no error nor a response even though the end point was called and file is being precessed in the backend, but nothing to the client which is quite strange!
– Abdenaceur Lichiheb
Nov 19 '18 at 11:29




There's no error nor a response even though the end point was called and file is being precessed in the backend, but nothing to the client which is quite strange!
– Abdenaceur Lichiheb
Nov 19 '18 at 11:29












2 Answers
2






active

oldest

votes


















1














I tried using your backend code, but in angular I used this :



window.location.href = "http://localhost:9001/rest/api/analyses/download";


And it start downloading successfully.






share|improve this answer





















  • Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
    – Abdenaceur Lichiheb
    Nov 19 '18 at 15:11



















1














It's seems that I missed arround with headers, while saving, this is the final version, it may help someone else:



Spring Boot



Add these configurations to ApplicationInit:



@Configuration
public static class WebConfig extends WebMvcConfigurerAdapter {

@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(-1);
configurer.setTaskExecutor(asyncTaskExecutor());
}

@Bean
public AsyncTaskExecutor asyncTaskExecutor() {
return new SimpleAsyncTaskExecutor("async");
}

}


And this to your controller:



@RequestMapping(value = "{analyseId}/download", method = RequestMethod.GET, produces = "application/zip")
public ResponseEntity<StreamingResponseBody> download(@PathVariable Long analyseId) throws IOException {
try {
Analyse analyse = analyseService.getAnalyse(analyseId);

final InputStream file =azureDataLakeStoreService.readFile(analyse.getZippedFilePath());
Long fileLength = azureDataLakeStoreService.getContentSummary(analyse.getZippedFilePath()).length;
StreamingResponseBody stream = outputStream ->
readAndWrite(file , outputStream);

String zipFileName = FilenameUtils.getName(analyse.getZippedFilePath());
return ResponseEntity.ok()
.header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + zipFileName)
.contentLength(fileLength)
.contentType(MediaType.parseMediaType("application/zip"))
.body(stream);
} catch (Exception e) {
e.printStackTrace();
return ExceptionMapper.toResponse(e);
}
}

private void readAndWrite(final InputStream is, OutputStream os)
throws IOException {
byte data = new byte[2048];
int read = 0;
while ((read = is.read(data)) >= 0) {
os.write(data, 0, read);
}
os.flush();
}


Angular



download(id) {
let url = URL + '/analyses/' + id + '/download';
const headers = new HttpHeaders().set('Accept', 'application/zip');
const req = new HttpRequest('GET', url, {
headers: headers,
responseType: 'blob',
observe: 'response',
reportProgress: true,
});
const dialogRef = this.dialog.open(DownloadInProgressDialogComponent);
this.http.request(req).subscribe(event => {
if (event.type === HttpEventType.DownloadProgress) {
dialogRef.componentInstance.progress = Math.round(100 * event.loaded / event.total) // download percentage
} else if (event instanceof HttpResponse) {
dialogRef.componentInstance.progress = 100;
this.saveToFileSystem(event, 'application/zip');
dialogRef.close();
}
});
}

private saveToFileSystem(response, type) {
const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const parts: string = contentDispositionHeader.split(';');
const filename = parts[1].split('=')[1];
const blob = new Blob([response.body], {
type: type
});
saveAs(blob, filename);
}





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53366704%2fangular-doesnt-download-a-file-from-a-stream-streamingresponsebody%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    I tried using your backend code, but in angular I used this :



    window.location.href = "http://localhost:9001/rest/api/analyses/download";


    And it start downloading successfully.






    share|improve this answer





















    • Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
      – Abdenaceur Lichiheb
      Nov 19 '18 at 15:11
















    1














    I tried using your backend code, but in angular I used this :



    window.location.href = "http://localhost:9001/rest/api/analyses/download";


    And it start downloading successfully.






    share|improve this answer





















    • Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
      – Abdenaceur Lichiheb
      Nov 19 '18 at 15:11














    1












    1








    1






    I tried using your backend code, but in angular I used this :



    window.location.href = "http://localhost:9001/rest/api/analyses/download";


    And it start downloading successfully.






    share|improve this answer












    I tried using your backend code, but in angular I used this :



    window.location.href = "http://localhost:9001/rest/api/analyses/download";


    And it start downloading successfully.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 19 '18 at 15:09









    Svg_af

    658




    658












    • Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
      – Abdenaceur Lichiheb
      Nov 19 '18 at 15:11


















    • Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
      – Abdenaceur Lichiheb
      Nov 19 '18 at 15:11
















    Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
    – Abdenaceur Lichiheb
    Nov 19 '18 at 15:11




    Thanks this actually works as the curl, however I cannot set a token using $window.location.href.
    – Abdenaceur Lichiheb
    Nov 19 '18 at 15:11













    1














    It's seems that I missed arround with headers, while saving, this is the final version, it may help someone else:



    Spring Boot



    Add these configurations to ApplicationInit:



    @Configuration
    public static class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    configurer.setDefaultTimeout(-1);
    configurer.setTaskExecutor(asyncTaskExecutor());
    }

    @Bean
    public AsyncTaskExecutor asyncTaskExecutor() {
    return new SimpleAsyncTaskExecutor("async");
    }

    }


    And this to your controller:



    @RequestMapping(value = "{analyseId}/download", method = RequestMethod.GET, produces = "application/zip")
    public ResponseEntity<StreamingResponseBody> download(@PathVariable Long analyseId) throws IOException {
    try {
    Analyse analyse = analyseService.getAnalyse(analyseId);

    final InputStream file =azureDataLakeStoreService.readFile(analyse.getZippedFilePath());
    Long fileLength = azureDataLakeStoreService.getContentSummary(analyse.getZippedFilePath()).length;
    StreamingResponseBody stream = outputStream ->
    readAndWrite(file , outputStream);

    String zipFileName = FilenameUtils.getName(analyse.getZippedFilePath());
    return ResponseEntity.ok()
    .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + zipFileName)
    .contentLength(fileLength)
    .contentType(MediaType.parseMediaType("application/zip"))
    .body(stream);
    } catch (Exception e) {
    e.printStackTrace();
    return ExceptionMapper.toResponse(e);
    }
    }

    private void readAndWrite(final InputStream is, OutputStream os)
    throws IOException {
    byte data = new byte[2048];
    int read = 0;
    while ((read = is.read(data)) >= 0) {
    os.write(data, 0, read);
    }
    os.flush();
    }


    Angular



    download(id) {
    let url = URL + '/analyses/' + id + '/download';
    const headers = new HttpHeaders().set('Accept', 'application/zip');
    const req = new HttpRequest('GET', url, {
    headers: headers,
    responseType: 'blob',
    observe: 'response',
    reportProgress: true,
    });
    const dialogRef = this.dialog.open(DownloadInProgressDialogComponent);
    this.http.request(req).subscribe(event => {
    if (event.type === HttpEventType.DownloadProgress) {
    dialogRef.componentInstance.progress = Math.round(100 * event.loaded / event.total) // download percentage
    } else if (event instanceof HttpResponse) {
    dialogRef.componentInstance.progress = 100;
    this.saveToFileSystem(event, 'application/zip');
    dialogRef.close();
    }
    });
    }

    private saveToFileSystem(response, type) {
    const contentDispositionHeader: string = response.headers.get('Content-Disposition');
    const parts: string = contentDispositionHeader.split(';');
    const filename = parts[1].split('=')[1];
    const blob = new Blob([response.body], {
    type: type
    });
    saveAs(blob, filename);
    }





    share|improve this answer


























      1














      It's seems that I missed arround with headers, while saving, this is the final version, it may help someone else:



      Spring Boot



      Add these configurations to ApplicationInit:



      @Configuration
      public static class WebConfig extends WebMvcConfigurerAdapter {

      @Override
      public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
      configurer.setDefaultTimeout(-1);
      configurer.setTaskExecutor(asyncTaskExecutor());
      }

      @Bean
      public AsyncTaskExecutor asyncTaskExecutor() {
      return new SimpleAsyncTaskExecutor("async");
      }

      }


      And this to your controller:



      @RequestMapping(value = "{analyseId}/download", method = RequestMethod.GET, produces = "application/zip")
      public ResponseEntity<StreamingResponseBody> download(@PathVariable Long analyseId) throws IOException {
      try {
      Analyse analyse = analyseService.getAnalyse(analyseId);

      final InputStream file =azureDataLakeStoreService.readFile(analyse.getZippedFilePath());
      Long fileLength = azureDataLakeStoreService.getContentSummary(analyse.getZippedFilePath()).length;
      StreamingResponseBody stream = outputStream ->
      readAndWrite(file , outputStream);

      String zipFileName = FilenameUtils.getName(analyse.getZippedFilePath());
      return ResponseEntity.ok()
      .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
      .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + zipFileName)
      .contentLength(fileLength)
      .contentType(MediaType.parseMediaType("application/zip"))
      .body(stream);
      } catch (Exception e) {
      e.printStackTrace();
      return ExceptionMapper.toResponse(e);
      }
      }

      private void readAndWrite(final InputStream is, OutputStream os)
      throws IOException {
      byte data = new byte[2048];
      int read = 0;
      while ((read = is.read(data)) >= 0) {
      os.write(data, 0, read);
      }
      os.flush();
      }


      Angular



      download(id) {
      let url = URL + '/analyses/' + id + '/download';
      const headers = new HttpHeaders().set('Accept', 'application/zip');
      const req = new HttpRequest('GET', url, {
      headers: headers,
      responseType: 'blob',
      observe: 'response',
      reportProgress: true,
      });
      const dialogRef = this.dialog.open(DownloadInProgressDialogComponent);
      this.http.request(req).subscribe(event => {
      if (event.type === HttpEventType.DownloadProgress) {
      dialogRef.componentInstance.progress = Math.round(100 * event.loaded / event.total) // download percentage
      } else if (event instanceof HttpResponse) {
      dialogRef.componentInstance.progress = 100;
      this.saveToFileSystem(event, 'application/zip');
      dialogRef.close();
      }
      });
      }

      private saveToFileSystem(response, type) {
      const contentDispositionHeader: string = response.headers.get('Content-Disposition');
      const parts: string = contentDispositionHeader.split(';');
      const filename = parts[1].split('=')[1];
      const blob = new Blob([response.body], {
      type: type
      });
      saveAs(blob, filename);
      }





      share|improve this answer
























        1












        1








        1






        It's seems that I missed arround with headers, while saving, this is the final version, it may help someone else:



        Spring Boot



        Add these configurations to ApplicationInit:



        @Configuration
        public static class WebConfig extends WebMvcConfigurerAdapter {

        @Override
        public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setDefaultTimeout(-1);
        configurer.setTaskExecutor(asyncTaskExecutor());
        }

        @Bean
        public AsyncTaskExecutor asyncTaskExecutor() {
        return new SimpleAsyncTaskExecutor("async");
        }

        }


        And this to your controller:



        @RequestMapping(value = "{analyseId}/download", method = RequestMethod.GET, produces = "application/zip")
        public ResponseEntity<StreamingResponseBody> download(@PathVariable Long analyseId) throws IOException {
        try {
        Analyse analyse = analyseService.getAnalyse(analyseId);

        final InputStream file =azureDataLakeStoreService.readFile(analyse.getZippedFilePath());
        Long fileLength = azureDataLakeStoreService.getContentSummary(analyse.getZippedFilePath()).length;
        StreamingResponseBody stream = outputStream ->
        readAndWrite(file , outputStream);

        String zipFileName = FilenameUtils.getName(analyse.getZippedFilePath());
        return ResponseEntity.ok()
        .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + zipFileName)
        .contentLength(fileLength)
        .contentType(MediaType.parseMediaType("application/zip"))
        .body(stream);
        } catch (Exception e) {
        e.printStackTrace();
        return ExceptionMapper.toResponse(e);
        }
        }

        private void readAndWrite(final InputStream is, OutputStream os)
        throws IOException {
        byte data = new byte[2048];
        int read = 0;
        while ((read = is.read(data)) >= 0) {
        os.write(data, 0, read);
        }
        os.flush();
        }


        Angular



        download(id) {
        let url = URL + '/analyses/' + id + '/download';
        const headers = new HttpHeaders().set('Accept', 'application/zip');
        const req = new HttpRequest('GET', url, {
        headers: headers,
        responseType: 'blob',
        observe: 'response',
        reportProgress: true,
        });
        const dialogRef = this.dialog.open(DownloadInProgressDialogComponent);
        this.http.request(req).subscribe(event => {
        if (event.type === HttpEventType.DownloadProgress) {
        dialogRef.componentInstance.progress = Math.round(100 * event.loaded / event.total) // download percentage
        } else if (event instanceof HttpResponse) {
        dialogRef.componentInstance.progress = 100;
        this.saveToFileSystem(event, 'application/zip');
        dialogRef.close();
        }
        });
        }

        private saveToFileSystem(response, type) {
        const contentDispositionHeader: string = response.headers.get('Content-Disposition');
        const parts: string = contentDispositionHeader.split(';');
        const filename = parts[1].split('=')[1];
        const blob = new Blob([response.body], {
        type: type
        });
        saveAs(blob, filename);
        }





        share|improve this answer












        It's seems that I missed arround with headers, while saving, this is the final version, it may help someone else:



        Spring Boot



        Add these configurations to ApplicationInit:



        @Configuration
        public static class WebConfig extends WebMvcConfigurerAdapter {

        @Override
        public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setDefaultTimeout(-1);
        configurer.setTaskExecutor(asyncTaskExecutor());
        }

        @Bean
        public AsyncTaskExecutor asyncTaskExecutor() {
        return new SimpleAsyncTaskExecutor("async");
        }

        }


        And this to your controller:



        @RequestMapping(value = "{analyseId}/download", method = RequestMethod.GET, produces = "application/zip")
        public ResponseEntity<StreamingResponseBody> download(@PathVariable Long analyseId) throws IOException {
        try {
        Analyse analyse = analyseService.getAnalyse(analyseId);

        final InputStream file =azureDataLakeStoreService.readFile(analyse.getZippedFilePath());
        Long fileLength = azureDataLakeStoreService.getContentSummary(analyse.getZippedFilePath()).length;
        StreamingResponseBody stream = outputStream ->
        readAndWrite(file , outputStream);

        String zipFileName = FilenameUtils.getName(analyse.getZippedFilePath());
        return ResponseEntity.ok()
        .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + zipFileName)
        .contentLength(fileLength)
        .contentType(MediaType.parseMediaType("application/zip"))
        .body(stream);
        } catch (Exception e) {
        e.printStackTrace();
        return ExceptionMapper.toResponse(e);
        }
        }

        private void readAndWrite(final InputStream is, OutputStream os)
        throws IOException {
        byte data = new byte[2048];
        int read = 0;
        while ((read = is.read(data)) >= 0) {
        os.write(data, 0, read);
        }
        os.flush();
        }


        Angular



        download(id) {
        let url = URL + '/analyses/' + id + '/download';
        const headers = new HttpHeaders().set('Accept', 'application/zip');
        const req = new HttpRequest('GET', url, {
        headers: headers,
        responseType: 'blob',
        observe: 'response',
        reportProgress: true,
        });
        const dialogRef = this.dialog.open(DownloadInProgressDialogComponent);
        this.http.request(req).subscribe(event => {
        if (event.type === HttpEventType.DownloadProgress) {
        dialogRef.componentInstance.progress = Math.round(100 * event.loaded / event.total) // download percentage
        } else if (event instanceof HttpResponse) {
        dialogRef.componentInstance.progress = 100;
        this.saveToFileSystem(event, 'application/zip');
        dialogRef.close();
        }
        });
        }

        private saveToFileSystem(response, type) {
        const contentDispositionHeader: string = response.headers.get('Content-Disposition');
        const parts: string = contentDispositionHeader.split(';');
        const filename = parts[1].split('=')[1];
        const blob = new Blob([response.body], {
        type: type
        });
        saveAs(blob, filename);
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 '18 at 11:09









        Abdenaceur Lichiheb

        8912729




        8912729






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53366704%2fangular-doesnt-download-a-file-from-a-stream-streamingresponsebody%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            Npm cannot find a required file even through it is in the searched directory

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith