Linux springBoot 资源上传问题

目录

    1.前言

    2.原因

    3.改良代码示例

    4.思路分析

##1.前言:

本来手头开发的项目在本地(windows环境)已经开发并测试完了,没有问题,之后改为部署到linux进行测试,部署后发现资源上传全部出现了异常(其它功能没有问题),着实头疼,耗费了几根头发后终于解决了,在此记录一下并分享给遇到相同问题的朋友

这里的path为.getClass().getResource("/").getPath()(class路径)+ uploadpath

  (备注:filePath是传过来的classpath加上业务的路径 )

这是最初的上传代码  功能相对比较简单 利用封装的二进制对象进行流的传输

该代码在Windows下是没问题的,但是查看日志发现在linux下目录就变成了奇怪的/home/cnki/项目名字/deployer/tomcat/work/Tomcat/localhost/knmarket-manage-api/file:/home/cnki/项目名字/项目名字.jar!/BOOT-INF/classes!/static/upload/product/pdf/-bash: !/BOOT-INF/classes!/static/upload/product/pdf/ 

##2.原因

查阅相关资料了解到, 由于项目是在linux下以jar方式运行的,那么前面传来的类路径就变为了以jar为基础的file:/home/cnki/项目名字/项目名字.jar!/BOOT-INF/classes! jar目录,因此导致判断是否存在的目录和transferTo的目录根本不是同一个目录(判断的目录为以jar为基础的类路径并被linux操作系统解析为linux的路径并创建;而传输的目录就是以jar为基础的类路径,但是根本无法上传 因为无法直接更改jar内部)

这也是为什么服务器上“莫名其妙”的创建了如下目录:

 

这种问题的原因可以总结为一句话:判断目录与实际上传目录不一致

##3.改良代码示例

万事开头难,明白了原因后就好说了,针对下进行处理就好了,如果是在linux下就获取当前jar运行的目录,并在该同级目录下新建static作为资源映射目录,上传和访问都指向该新的目录即可而之前的逻辑是上传到项目中的static目录

(PS:目前我的需求只是在Windows开发环境下调试,正式部署是在linux系统下以jar方式运行,所以以下改进代码只是针对这两种情况,如果说你想在Windows下以jar运行可以参考linux分支进行处理)

    public static boolean uploadFile(String filePath, String fileName, MultipartFile multipartFile) {
        String osname = System.getProperties().getProperty("os.name");
        File file = null;
        File fileSource = new File(file, fileName);
        try {
            if(osname.toLowerCase().contains("windows")){
                file = new File(filePath);
                if (!file.exists()) {
                    file.mkdirs();
                }
                multipartFile.transferTo(new File(filePath, fileName));
            }else if(osname.toLowerCase().contains("linux")){
                String runPath = new File(ResourceUtils.getURL("classpath:").getPath()).getParentFile().getParentFile().getParent().replace("file:", "");
                String tempPath[] = filePath.split("/static");
                file = new File(runPath + "/static" + tempPath[tempPath.length - 1]);
                if (!file.exists()) {
                    file.mkdirs();
                }
                multipartFile.transferTo(new File(runPath + "/static" + tempPath[tempPath.length - 1] + fileName));
            }
        } catch (IOException e) {
            log.error("上传文件失败");
            e.printStackTrace();
            return false;
        }
        return true;
    }
##4.思路分析
Linux系统下首先获取到jar运行的路径:runPath
new File(runPath + "/static" + tempPath[tempPath.length - 1]);//这一行是为了 拿到之前上传到项目中的路径 并判断路径是否存在   该路径就是服务器上运行的jar同级目录下的static/../...
至此服务器已经可以正常存取资源到相应目录下了 以下为示例:
假设/home/ins/下有运行的
demo.jar项目  static目录
如上代码最终在服务器上的
  上传目录为:/home/ins/static/img/main/
  访问目录为:http://ip:port/项目名字/img/main/(springBoot的默认静态资源映射目录就是classpath下的static)
最终屁颠屁颠跑到vue前台进行测试

  发现图片终于可以正常存储并获取了(长舒一口气ε=(´ο`*)))唉不容易)

 至此,打完,收工 

结语:新人第一次发博客 本文如存在理解有偏差或错误观点,欢迎朋友们指出


posted @ 2021-08-24 17:23  gysm-slf  阅读(287)  评论(0)    收藏  举报