文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

cannot be resolved to absolute file path because it does not reside in the file system 问题解决

2023-09-07 17:23

关注

https://cloud.tencent.com/developer/article/2193203

项目场景:

在Springboot中利用Resource来获取文件并在前端返回该文件, 本地测试正常, 打包到远程报错: cannot be resolved to absolute file path because it does not reside in the file system


问题描述:

紧接上一个问题: 项目打包成 jar 后包无法读取src/main/resources下文件, 在Springboot打包之后, 无法读取到jar包内的文件, 因此采取Resource来获取jar内相对路径地址的文件. 只有一个需要下载文件的时候没有问题, 然后在指定文件夹下新增一个文件后本地下载正常, 打包后下载出现问题: 下载该文件时, 后端抛出异常, 异常如下

class path resource [static/xxx模板.xlsx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/mis-project-java-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/%e5%b7%a5%e8%b5%84%e8%a1%a8%e6%a8%a1%e6%9d%bf.xlsx

复制


原因分析:

需要下载文件存放的地址:

修改前代码:

    @Override    @SneakyThrows(IOException.class)    public HttpServletResponse downloadFile(HttpServletRequest request, HttpServletResponse response) {        //设置文件路径        org.springframework.core.io.Resource resource = new ClassPathResource("static/" + "xxx模板.xlsx");        if (resource.exists()) {            //异常在下一行抛出            File file = resource.getFile();            response.setCharacterEncoding("UTF-8");            response.setContentType("application/vnd.ms-excel");            String fileName = resource.getURI().toString().substring(resource.getURI().toString().lastIndexOf("/") + 1);            response.setHeader("content-disposition", "attachment;filename=" + fileName);            response.flushBuffer();            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));            OutputStream os = response.getOutputStream();            byte[] buffer = new byte[1024];            int i = bis.read(buffer);            while (i != -1) {                os.write(buffer, 0, i);                i = bis.read(buffer);            }            if (bis != null) {                bis.close();            }            return response;        }        return null;    }

复制

对问题部分本地断点调试

本地断点调试:

  1. 可以看到, 调用的是 AbstractFileResolvingResource下的getFIle 方法. 然后该方法会调用 ResourceUtils下的getFile() 方法

  1. 可以看到在ResourceUtils下的getFile() 方法中, 因为 resourceUrl.getProtocol() 为File, 说明该url 地址对应的资源是文件, 所以直接返回这个文件

  1. 后续源码如何返回这个文件可以自己继续深入

对问题部分远程断点调试:

  1. 依旧是进入 resource.getFile(); 的方法内. 因为当前 url的protocol 属性时 jar, 不是vfs, 依旧走的是ResourceUtils下的getFile() 方法
  1. 在ResourceUtils下的getFile() 方法中, 因为 resourceUrl.getProtocol() 为jar, 因此会抛出异常

  1. 异常抛出后被全局捕获, 然后在前端显示


解决方案:

通过上面的调试我们可以看到, org.springframework.core.io.Resource 这个类的getFile()方法, 会自动获取构建resource对象带参构造中的url, 然后根据这个url确定该文件的类型. 因为在本地时调试时, 通过resource.getFile()获取的url类型的 protocol 属性为File, 所以可以自动生成文件; 然而在将项目打包成jar部署在服务器上时, 因为该文件是在jar里面的. 因此通过resource.getFile()获取的url类型的 protocol 属性为jar. 所以抛出该异常 cannot be resolved to absolute file path because it does not reside in the file system: 文件url.

因此, 方法有两种: 一种是直接将该文件放入服务器其他目录下而不是在jar包中. 另一种就是通过流来获取jar里面的文件. 而本人采取第二种方式, 通过输入流来读取jar内的文件, 然后通过输出流将其输出.


修改后的代码

@Override@SneakyThrows(IOException.class)public HttpServletResponse downloadFile(HttpServletRequest request, HttpServletResponse response) {    //设置文件路径    org.springframework.core.io.Resource resource = new ClassPathResource("static/" + "xxx模板.xlsx");    if (resource.exists()) {        response.setCharacterEncoding("UTF-8");        response.setContentType("application/vnd.ms-excel");        String fileName = resource.getURI().toString().substring(resource.getURI().toString().lastIndexOf("/") + 1);        response.setHeader("content-disposition", "attachment;filename=" + fileName);        response.flushBuffer();        //放弃使用直接获取文件的方式, 改成使用流的方式        BufferedInputStream bis = new BufferedInputStream(resource.getInputStream());        OutputStream os = response.getOutputStream();        byte[] buffer = new byte[1024];        int i = bis.read(buffer);        while (i != -1) {            os.write(buffer, 0, i);            i = bis.read(buffer);        }        if (bis != null) {            bis.close();        }        return response;    }    return null;}

来源地址:https://blog.csdn.net/trusause/article/details/128401059

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯