Angular不会从流中下载文件(StreamingResponseBody)

编程入门 行业动态 更新时间:2024-10-24 14:17:53
本文介绍了Angular不会从流中下载文件(StreamingResponseBody)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用angular下载大文件,对于后端,我正在使用spring boot,这是端点的代码:

@RequestMapping(值="/下载",方法= RequestMethod.GET)公共StreamingResponseBody下载(@PathVariable字符串路径)引发IOException {最终InputStream文件= azureDataLakeStoreService.readFile(path);return(os)->{readAndWrite(file,os);};}私有无效的readAndWrite(最终InputStream是,OutputStream os)引发IOException {字节[]数据=新字节[2048];int读取= 0;而(((read = is.read(data))> = 0){System.out.println(附加到文件");os.write(数据,0,读取);}os.flush();}

当我尝试使用curl获取文件时,它可以工作,并且可以看到正在下载的文件,并且文件的大小正在增加:

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

但是,当我尝试使用angular下载文件时,即使请求成功,也无法正常工作,并且在日志中可以看到多次显示"append to file"的文本,但没有下载任何内容浏览器,这是我的代码:

this.http.get(URL,{标头:标头,responseType:'blob',观察:'response'}).subscribe(response => {const contentDispositionHeader:字符串= response.headers.get('Content-Disposition');常量部分:string [] = contentDispositionHeader.split(';');const filename = parts [1] .split('=')[1];const blob = new Blob([response.body],{类型:"application/zip"});saveAs(blob,文件名);});

saveAs()属于

解决方案

似乎我错过了带有标头的arround,在保存的同时,这是最终版本,可能会帮助其他人:

Spring Boot

将这些配置添加到 ApplicationInit :

@Configuration公共静态类WebConfig扩展了WebMvcConfigurerAdapter {@Override公共无效configureAsyncSupport(AsyncSupportConfigurer配置器){configurer.setDefaultTimeout(-1);configurer.setTaskExecutor(asyncTaskExecutor());}@豆公共AsyncTaskExecutor asyncTaskExecutor(){返回新的SimpleAsyncTaskExecutor("async");}}

然后将其发送给您的控制器:

@RequestMapping(值="{analyseId}/download",方法= RequestMethod.GET,产生="application/zip")公共ResponseEntity< StreamingResponseBody>下载(@PathVariable Long analyseId)引发IOException {尝试 {分析analyze = analyseService.getAnalyse(analyseId);最终InputStream文件= azureDataLakeStoreService.readFile(analyse.getZippedFilePath());长文件长度= azureDataLakeStoreService.getContentSummary(analyse.getZippedFilePath()).length;StreamingResponseBody stream = outputStream->readAndWrite(file,outputStream);字符串zipFileName = FilenameUtils.getName(analyse.getZippedFilePath());返回ResponseEntity.ok().header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,HttpHeaders.CONTENT_DISPOSITION).header(HttpHeaders.CONTENT_DISPOSITION,附件;文件名=" + zipFileName).contentLength(fileLength).contentType(MediaType.parseMediaType("application/zip")).body(stream);} catch(Exception e){e.printStackTrace();返回ExceptionMapper.toResponse(e);}}私有无效的readAndWrite(最终InputStream是,OutputStream os)引发IOException {字节[]数据=新字节[2048];int读取= 0;而(((read = is.read(data))> = 0){os.write(数据,0,读取);}os.flush();}

角度

download(id){让url = URL +'/analyses/'+ id +'/download';const headers = new HttpHeaders().set('Accept','application/zip');const req = new HttpRequest('GET',url,{标头:标头,responseType:"blob",观察:响应",reportProgress:是的,});const dialogRef = this.dialog.open(DownloadInProgressDialogComponent);this.http.request(req).subscribe(event => {如果(event.type === HttpEventType.DownloadProgress){dialogRefponentInstance.progress = Math.round(100 * event.loaded/event.total)//下载百分比} else if(HttpResponse的事件instance){dialogRefponentInstance.progress = 100;this.saveToFileSystem(event,'application/zip');dialogRef.close();}});}私人saveToFileSystem(响应,类型){const contentDispositionHeader:字符串= response.headers.get('Content-Disposition');常量部分:string [] = contentDispositionHeader.split(';');const filename = parts [1] .split('=')[1];const blob = new Blob([response.body],{类型:类型});saveAs(blob,文件名);}

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>" 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.

解决方案

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) { dialogRefponentInstance.progress = Math.round(100 * event.loaded / event.total) // download percentage } else if (event instanceof HttpResponse) { dialogRefponentInstance.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); }

更多推荐

Angular不会从流中下载文件(StreamingResponseBody)

本文发布于:2023-11-26 07:09:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1633127.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文件   Angular   StreamingResponseBody

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!