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前台进行测试

发现图片终于可以正常存储并获取了(长舒一口气ε=(´ο`*)))唉不容易)
至此,打完,收工
结语:新人第一次发博客 本文如存在理解有偏差或错误观点,欢迎朋友们指出