spring - 找不到可接受的文件下载表示
问题描述
我想使用这个 Angular 6 代码实现文件下载:
休息API:
private static final Logger LOG = LoggerFactory.getLogger(DownloadsController.class);
private static final String EXTERNAL_FILE_PATH = "/Users/test/Documents/blacklist_api.pdf";
@GetMapping("export")
public ResponseEntity<FileInputStream> export() throws IOException {
File pdfFile = Paths.get(EXTERNAL_FILE_PATH).toFile();
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return ResponseEntity.ok().headers(headers).contentLength(pdfFile.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(new FileInputStream(pdfFile));
}
服务:
import {Injectable} from '@angular/core';
import {HttpClient, HttpParams} from "@angular/common/http";
import {Observable} from "rxjs/index";
import {environment} from "../../../environments/environment";
import {HttpUtils} from "../common/http-utils";
import { map } from 'rxjs/operators';
import {Http, ResponseContentType} from '@angular/http';
@Injectable({
providedIn: 'root'
})
export class DownloadService {
constructor(private http: HttpClient) {
}
downloadPDF(): any {
return this.http.get(environment.api.urls.downloads.getPdf, {
responseType: 'blob'
})
.pipe(
map((res: any) => {
return new Blob([res.blob()], {
type: 'application/pdf'
})
})
);
}
}
零件:
import {Component, OnInit} from '@angular/core';
import {DownloadService} from "../service/download.service";
import {ActivatedRoute, Router} from "@angular/router";
import {flatMap} from "rxjs/internal/operators";
import {of} from "rxjs/index";
import { map } from 'rxjs/operators';
@Component({
selector: 'app-download',
templateUrl: './download.component.html',
styleUrls: ['./download.component.scss']
})
export class DownloadComponent implements OnInit {
constructor(private downloadService: DownloadService,
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
}
export() {
this.downloadService.downloadPDF().subscribe(res => {
const fileURL = URL.createObjectURL(res);
window.open(fileURL, '_blank');
});
}
}
该文件存在于目录中,但是当我尝试下载它时出现错误:
18:35:25,032 WARN [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (default task-2) Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
你知道我该如何解决这个问题吗?我是否需要添加其他配置才能通过 Angular Web UI 下载文件?
我使用 spring-boot-starter-parent 版本 2.1.0.RELEASE
解决方案
FileSaver npmjs.com/package/ngx-filesaver是 Angular6 中文件下载的最佳库,但它在 ios 设备中存在各种问题。我们通过编写自己的方法并有条件地处理它来修复它。
零件
download() {
this.downloadService.downloadPDF().subscribe(async (res: Blob) => {
if (this.isIOSMobileDevice) {
const file = new File([res], fileName, { type: 'application/pdf' });
const dataStringURL: any = await this.fileService.readFile(file);
this.hrefLink = this.sanitizer.bypassSecurityTrustUrl(dataStringURL);
} else {
saveFile(res, fileName);
}
});
}
export const saveFile = (blobContent: Blob, fileName) => {
const isIOS = (!!navigator.platform.match(/iPhone|iPod|iPad/)) || (navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2);
const blob = new Blob([blobContent], { type: 'application/pdf' });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
document.body.appendChild(link);
link.href = url;
link.target = '_self';
link.download = fileName;
link.click();
document.body.removeChild(link);
}
};
文件服务
async readFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
HTML 代码
<a *ngIf="isIOSMobileDevice" [href]="hrefLink"
target="_blank">Download</a>
<a *ngIf="!isIOSMobileDevice" href="javascript:;" (click)="download"
target="_blank">Download</a>
对于 ios 移动设备,必须在先决条件中调用下载方法,以便我们获得 hrefLink。
推荐阅读
- c# - 打开一个 xAPI 包并显示以前完成的百分比和勾选的完整幻灯片
- python-3.x - 为什么在使用 AWS Lambda 层与 AWS SAM 部署包时存在大小差异
- node.js - 找不到名称“TaskData”
- python - Alembic 为 Geometry 列生成任意类型更改
- c# - 如何让纹理在我的精灵上滚动?
- php - 如何创建显示前三页和后三页的分页
- php - 儿童组 Laravel 合集
- php - 注册用户时未定义的变量 - Laravel
- docker - 无法运行基于 ARM docker 构建的 ARM 二进制文件 - 找不到小程序
- android - 如何工作父布局点击所有子布局?