问题原因
Resource resource = new ClassPathResource("static/test.xlsx");
if (resource.exists()) {
try {
File file = resource.getFile();
...
} catch (IOException e) {
throw new RuntimeException(e);
}
}
将test.xlsx文件放到resources的static目录下,当使用以上代码读取文件内容时,在本地运行正常,打成jar包上服务器之后报异常信息cannot be resolved to absolute file path because it does not reside in the file system
本地调试
通过打断点的形式来分析下问题出现的原因,该方法会进入AbstractFileResolvingResource类
public File getFile() throws IOException {
URL url = this.getURL();
return url.getProtocol().startsWith("vfs") ? AbstractFileResolvingResource.VfsResourceDelegate.getResource(url).getFile() : ResourceUtils.getFile(url, this.getDescription());
}
因为url.getProtocol()
为file,所以会走ResourceUtils.getFile(url, this.getDescription());
,进入该方法
public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {
Assert.notNull(resourceUrl, "Resource URL must not be null");
if (!"file".equals(resourceUrl.getProtocol())) { //注意注意,这是“代码块”
throw new FileNotFoundException(description + " cannot be resolved to absolute file path because it does not reside in the file system: " + resourceUrl);
} else {
try {
return new File(toURI(resourceUrl).getSchemeSpecificPart());
} catch (URISyntaxException var3) {
return new File(resourceUrl.getFile());
}
}
}
因为 resourceUrl.getProtocol()
为File,说明该url 地址对应的资源是文件,所以直接返回这个文件。
远程调试
将jar包发布到服务器之后,用本地远程调试远程代码,我们会发现此时url.getProtocol()
为jar,所以会在“代码块”处抛出异常。
cannot be resolved to absolute file path because it does not reside in the file system
解决方案
一、将要使用的文件直接放到服务器的固定目录下,直接从服务器中获取而不是从jar包获取;
二、通过流来获取jar里面的文件;
Resource resource = new ClassPathResource("static/test.xlsx");
// 以流的形式读取文件内容
try (InputStream inputStream = resource.getInputStream()) {
return FileCopyUtils.copyToByteArray(inputStream);
}