SpringBoot项目打包部署,读取jar里面的文件报错500,异常日志关键提示
cannot be resolved to absolute file path because it does not reside in the file system
报错定位
is = new FileInputStream(ResourceUtils.getFile("classpath:static/data_template/biz/export_XXXX_report.xlsx"));
从报错可看到读取文件路径XXX.jar!**.xlsx,XXX.jar就是打成jar,里面包含了需要读取的模板文件
具体Spring core(版本5.2.12)包源码ResourceUtils
public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {
Assert.notNull(resourceUrl, "Resource URL must not be null");
if (!URL_PROTOCOL_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);
}
try {
return new File(toURI(resourceUrl).getSchemeSpecificPart());
}
catch (URISyntaxException ex) {
// Fallback for URLs that are not valid URIs (should hardly ever happen).
return new File(resourceUrl.getFile());
}
}
解决办法如下:
//获得文件流时,因为读取的文件是在打好jar文件里面,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
//ResourcePatternResolver的实现方法,可以匹配到各种部署时的各种文件类型例如war,jar,zip等等findPathMatchingResources
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("static/data_template/biz/XXXX.xlsx");
Resource resource = resources[0];
InputStream is = resource.getInputStream();
Spring源码(PathMatchingResourcePatternResolver)关键代码段
@Override
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// a class path resource (multiple resources for same name possible)
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
return findPathMatchingResources(locationPattern);
}
else {
// all class path resources with the given name
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
// Generally only look for a pattern after a prefix here,
// and on Tomcat only after the "*/" separator for its "war:" protocol.
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
locationPattern.indexOf(':') + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
}
else {
// a single resource with the given name
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
发布到服务器,问题解决!!
标签:resolved,resourceUrl,jar,locationPattern,报错,file,path From: https://www.cnblogs.com/fuqian/p/16836892.html