【SpringBoot】本地到发布环境的文件上传bug记录

【环境说明】

本地测试环境:win10 + tomact

发布测试环境:win server 2012 R2  + welogic 

【代码说明】

后端接收前端的文件MultipartFile[] uploadFileList,完成上传操作

void UploadUtils(MultipartFile[] uploadFileList, Integer articleID, String pathURL, String type) throws IOException {
        for (MultipartFile uploadFile : uploadFileList) {
            // 获取文件原始名称
            String oldFileName = uploadFile.getOriginalFilename();
            // 获取文件后缀
            String extension = "." + FilenameUtils.getExtension(uploadFile.getOriginalFilename());
            // 生成新的文件名
            String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "_" + UUID.randomUUID().toString().replace("-", "") + extension;

            System.out.println("oldFileName :" + oldFileName);
            System.out.println("newFileName :" + newFileName);

            // 文件上传到指定文件夹[pathURL]下 - 项目地址路径越简单越好,不要有特殊字符比如“[]”,同时用“\\”不要用“/”
            String ContextPath = ResourceUtils.getURL("classpath:").getPath();
            String accURL = pathURL + new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String dateDirPath = ContextPath + accURL;

            System.out.println("ContextPath: " + ContextPath); // /F:/project_name/target/classes/
            System.out.println("accURL: " + accURL);  // static/images/2021-03-26
            System.out.println("dateDirPath: " + dateDirPath); // /F:/project_name/target/classes/static/images/2021-03-26

            File dateDir = new File(dateDirPath);
            if (!dateDir.exists()) {
                dateDir.mkdirs(); // 创建新文件夹
            }
            
            uploadFile.transferTo(new File(dateDir, newFileName)); // 文件上传

            // 将附件信息存入数据库保存
            Acc acc = new Acc();
            acc.setArticleID(articleID);
            acc.setAccName(oldFileName);
            acc.setAccNameUUID(newFileName);
            acc.setAccURL(accURL);
            acc.setAccType(type); // 设置文件类型
            accMapper.insert(acc);
        }
    }

实现文件上传的其实只有这么一句话

uploadFile.transferTo(new File(dateDir, newFileName));

本地测试全部通过,发布到服务器上就开始一路狂出bug

#1 -> 报错 java.io.FileNotFoundException:XXX (文件名、目录名或卷标语法不正确)

后台打印输出的文件地址,反复核对没有问题 

后来看到一篇文章https://blog.csdn.net/weixin_41790646/article/details/89004538,指明了方向是transferTo的问题

之前用的是transferTo(Fie file),修改成transferTo(Path dest)

//uploadFile.transferTo(new File(dateDir, newFileName)); // 文件上传  
Path filePath = Paths.get(dateDirPath, newFileName);
uploadFile.transferTo(filePath);

出现问题的原因是使用传参File的方式会在路径之前加上一长串的无用路径,我们制定的文件夹路径被默认识别成了相对路径,如果是需要指定某个文件夹,最好是用Path的方式传参。

#2-> java.nio.file.InvalidPathException

出现这个问题的原因是地址前面多了个/ ,直接去掉就好

dateDirPath = dateDirPath.substring(1, dateDirPath.length());

再次运行,ok没问题了。

[完整代码]

void UploadUtils(MultipartFile[] uploadFileList, Integer articleID, String pathURL, String type) throws IOException {
        for (MultipartFile uploadFile : uploadFileList) {
            // 获取文件原始名称
            String oldFileName = uploadFile.getOriginalFilename();
            // 获取文件后缀
            String extension = "." + FilenameUtils.getExtension(uploadFile.getOriginalFilename());
            // 生成新的文件名
            String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "_" + UUID.randomUUID().toString().replace("-", "") + extension;

            System.out.println("oldFileName :" + oldFileName);
            System.out.println("newFileName :" + newFileName);

            // 文件上传到指定文件夹[pathURL]下 - 项目地址路径越简单越好,不要有特殊字符比如“[]”,同时用“\\”不要用“/”
            String ContextPath = ResourceUtils.getURL("classpath:").getPath();
            String accURL = pathURL + new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String dateDirPath = ContextPath + accURL;

            //处理'/'
            dateDirPath = dateDirPath.substring(1, dateDirPath.length());

            System.out.println("ContextPath: " + ContextPath); // /F:/project_name/target/classes/
            System.out.println("accURL: " + accURL);  // static/images/2021-03-26
            System.out.println("dateDirPath: " + dateDirPath); // /F:/project_name/target/classes/static/images/2021-03-26

            File dateDir = new File(dateDirPath);
            if (!dateDir.exists()) {
                dateDir.mkdirs(); // 创建新文件夹
            }
            try{
//                uploadFile.transferTo(new File(dateDir, newFileName)); // 文件上传
                Path filePath = Paths.get(dateDirPath, newFileName);
                uploadFile.transferTo(filePath);
            } catch (Exception e){
                e.printStackTrace();
            }

            // 将附件信息存入数据库保存
            Acc acc = new Acc();
            acc.setArticleID(articleID);
            acc.setAccName(oldFileName);
            acc.setAccNameUUID(newFileName);
            acc.setAccURL(accURL);
            acc.setAccType(type); // 设置文件类型
            accMapper.insert(acc);
        }
    }

[参考]

transferto遇到的问题

https://blog.csdn.net/weixin_41790646/article/details/89004538

文件路径的描述与操作 Path & Paths

https://juejin.cn/post/6844904036928339976

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值