首页 > 其他分享 >SpringBoot文件上传丢失Bug记录

SpringBoot文件上传丢失Bug记录

时间:2023-02-15 16:13:12浏览次数:67  
标签:文件 file SpringBoot dest tmpFile File new 上传 Bug

SpringBoot文件上传丢失Bug记录

报错如下:

java.io.FileNotFoundException: C:\Users\zbz12\AppData\Local\Temp\tomcat.708075972435741143.8080\work\Tomcat\localhost\community.\img\c1e0c03994754a278d56b5abd67f2f06.jpg (系统找不到指定的路径。)

实际文件位置:

community:
  path:
    domain: http://localhost:8080  #域名
    upload: ./img # 默认本地文件存储位置

涉及程序段:

// 生成随机文件名
fileName = CommunityUtil.generateUUID() + suffix;
// 确定文件存放的路径
File tmpFile = new File(uploadPath + "/" + fileName);
try {
    if (!tmpFile.exists()) {
        new File(uploadPath).mkdirs();
    }
    // 存储文件
    headerImage.transferTo(tmpFile);
} catch (IOException e) {
    log.error("上传文件失败: " + e.getMessage());
    throw new RuntimeException("上传文件失败,服务器发生异常!", e);
}

从上面配置等内容我们可知,Spring存储文件的位置和我们配置的位置并不一致,而去配置文件夹下可发现对应文件夹已经创建,这应该是MultipartFile方法执行的问题。所以我们在transferTo(tmpFile)行打断点进行错误排查。

打断点进行Dbug调试

@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
 this.part.write(dest.getPath());
 if (dest.isAbsolute() && !dest.exists()) {//文件路径是绝对路径且非空
  // Servlet 3.0 Part.write is not guaranteed to support absolute file paths:  
  // may translate the given path to a relative location within a temp dir
  // (e.g. on Jetty whereas Tomcat and Undertow detect absolute paths).
  // At least we offloaded the file from memory storage; it'll get deleted
  // from the temp dir eventually in any case. And for our user's purposes,
  // we can manually copy it to the requested location as a fallback.
  // 翻译:Servlet 3.0 Part.write不保证支持绝对文件路径: 可以将给定路径转换为临时目录内的相对位置 (例如,在Jetty上,而Tomcat和Undertow检测绝对路径)。至少我们从内存存储中卸载了文件; 无论如何,它最终都会从临时目录中删除。为了我们用户的目的,我们可以手动将其复制到请求的位置作为后备。
  FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest.toPath()));
 }

从上面我们可以看出part.write(dest.getPath());是相对路径执行的方法,而我配置的就是相对路径,进入write继续查看。

@Override
public void write(String fileName) throws IOException {
    File file = new File(fileName);
    if (!file.isAbsolute()) {
        file = new File(location, fileName);//多出一个参数 location 
    }
    try {
        fileItem.write(file);
    } catch (Exception e) {
        throw new IOException(e);
    }
}

从注释行可看出我们的文件路径被篡改了,这也是我们报错文件位置不一致的原因。

image-20230215131333209

去文件夹下查看也没有文件,这是因为上述代码并没有创建我们定义的ing文件夹,更改文件位置代码验证一下

image-20230215133011484

思路正确,但感觉location参数有点不明所以,去Spring官方看看有没有相关insser

When i use transferTo() to copy a uploadfile to a relative address,the file is missing

image-20230215142356348

跟进到#19822,大致了解了这样操作的原因,但我还是想用相对路径操作

解决办法如下:

  • 使用public void transferTo(Path dest)方法,代码如下:

    // 确定文件存放的路径
    Path path = Paths.get(uploadPath + "/" + fileName);
    File tmpFile = new File(uploadPath);
    try {
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }
        // 存储文件
        headerImage.transferTo(path);
    } catch (IOException e) {
        log.error("上传文件失败: " + e.getMessage());
        throw new RuntimeException("上传文件失败,服务器发生异常!", e);
    }
    

标签:文件,file,SpringBoot,dest,tmpFile,File,new,上传,Bug
From: https://www.cnblogs.com/touchTomorrow/p/17123398.html

相关文章

  • springboot在test的时候,new的类报空指针
    ok@ComponentpublicclassFifthGithubCrawler{@AutowiredprivateKBComponentVersionRepositoryversionRepository;/***导出所有数据到json......
  • SpringBoot 参数及性能优化
    SpringBoot性能优化 组件自动扫描带来的问题默认情况下,我们会使用@SpringBootApplication注解来自动获取应用的配置信息,但这样也会给应用带来一些副作用。使用这个注解后......
  • CentOS中使用Dockerfile部署带websocket的SpringBoot的jar包
    场景CentOS7中使用Dockerfile部署后台jar包在上面使用Dockerfile定制的镜像部署了一个普通的jar包, 如果是jar包里面包含websocket的使用,流程也是一样。websocket所使用的......
  • 如何有效地报告 Bug
    如何有效地报告Bug作者:SimonTatham专业的自由软件程序员翻译:Dasn[English|Português|简体中文|Česky|Dansk|Deutsch|Español|Français|Magyar......
  • Java:SpringBoot整合Knife4j(Swagger)提供接口文档
    spring-boot版本2.7.71、引入Maven坐标pom.xml<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId>......
  • 【转载】前端大文件上传和下载(分片上传)
    版权声明:本文为CSDN博主「BreenCL」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/baoyin0822/article/details/12......
  • SpringBoot常用注解大全
    常用注解概览这里整理了一张SpringBoot常用注解的思维导图,本文主要讲解这些注解的用法。 组件相关注解@ComponentScan默认扫描当前包及其子包下面被@component,@Cont......
  • 基于JAVA+SpringBoot+VUE的心理健康测试系统的设计与实现
    ✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战......
  • 大文件分块上传
    #1.项目背景由于用户需求,需要上传大量图片,只能通过上传压缩包的形式上传,可是压缩包过大时,又会出现上传超时的情况,故需要将压缩包分块上传,然后解压缩图片、若图片过大则再......
  • winscp上传数据慢
    1. 问题描述     用winscp连接 板子时, 有时上传速度很慢。2. 解决方法    将电脑的网口 和 板子的网卡都设置成 自协商模式(1)将板子的网......