无法下载文件:无法解析为 URL,因为它不存在

Posted

技术标签:

【中文标题】无法下载文件:无法解析为 URL,因为它不存在【英文标题】:Cannot download file: cannot be resolved to URL because it does not exist 【发布时间】:2019-04-13 20:14:04 【问题描述】:

我想使用这个 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<InputStreamResource> export() throws IOException 
    ClassPathResource pdfFile = new ClassPathResource(EXTERNAL_FILE_PATH);

    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.contentLength())
            .contentType(MediaType.parseMediaType("application/pdf"))
            .body(new InputStreamResource(pdfFile.getInputStream()));

服务:

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');
    );         
   

组件:

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');
    );         
   

当我点击下载按钮时,我得到了这个 Spring 错误:

15:28:02,819 ERROR [org.springframework.boot.web.servlet.support.ErrorPageFilter] (default task-1) Forwarding to error page from request [/downloads/export] due to exception [class path resource [Users/test/Documents/blacklist_api.pdf] cannot be resolved to URL because it does not exist]: java.io.FileNotFoundException: class path resource [Users/test/Documents/blacklist_api.pdf] cannot be resolved to URL because it does not exist
    at deployment.test_admin.war//org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:195)

该文件存在于目录中,但看起来它位于 war 包之外,并且我无法访问它。有没有办法配置Java来访问和下载?

【问题讨论】:

ClassPathResource(path) 文档中的注释:将删除前导斜杠,因为 ClassLoader 资源访问方法将不接受它。 那我应该改变什么? 我认为这里更大的问题是ClassPathResource 不能引用文件系统的任意部分——它只能从你当前的类路径中找到资源。在这种情况下,也没有必要——为什么不直接使用FileInputStream(name) 【参考方案1】:

由于您使用的是 ClasspathResource,因此您只能获取类路径“”的文件。

如果您的文件位于类路径之外,则无法以这种方式获取它。

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<InputStreamResource> 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));

我改变了你获取文件的方式,为 File 而不是 ClassPathResource。

我修改了那段代码,如果有任何错误,请见谅。希望对你有帮助

【讨论】:

我得到了 File 类型的方法 contentLength() 是未定义的 为方法length()改一下 我收到错误Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation] 你可能需要在你的 getMapping 中设置你的produceType,比如@GetMapping(path="export",produces="application/pdf") 无论如何你有一个例子如何从这个link的REST下载pdf文件

以上是关于无法下载文件:无法解析为 URL,因为它不存在的主要内容,如果未能解决你的问题,请参考以下文章

无法在额外属性扩展上获取属性“compileSdkVersion”,因为它不存在 打开文件

无法以 Angular 5 下载文件

无法从解析服务器下载大于 20mb 的 pdf 文件

无法使用python从URL下载文件

无法从密钥环文件 secring.gpg 中检索密钥,因为它不存在

NSPOSIXErrorDomain 哪里下载文件