• SpringBoot上传文件夹


    SpringBoot上传文件夹

    前言

    个人开发过程中的经验总结

    前端

    此处以vue3为例

    <template>
      <form @submit.prevent="uploadFiles" ref="form">
        <input
          type="file"
          name="folder"
          ref="folderInput"
          multiple
          webkitdirectory
        />
        <button type="submit">上传button>
      form>
    template>
    
    <script setup>
    import { ref } from "vue";
    
    const folderInput = ref(null);
    const form = ref(null);
    
    const uploadFiles = () => {
      const formData = new FormData(form.value);
    
      // 发送数据到服务器
      fetch("http://localhost:8080/file/uploadFolder", {
        method: "POST",
        body: formData,
      })
        .then((response) => {
          if (!response.ok) {
            throw new Error("上传失败");
          }
          return response.json(); // 如果服务器返回JSON格式的响应,可以解析为JSON
        })
        .then((data) => {
          // 处理成功的响应,可以根据需要更新UI或执行其他操作
          console.log("上传成功:", data);
        })
        .catch((error) => {
          // 处理错误
          console.error("上传失败:", error);
        });
    };
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    后端

    FileController

    @RestController
    @RequestMapping("/file/")
    @CrossOrigin
    public class FileController {
    
        @PostMapping("/uploadFolder")
        public Result uploadFolder(MultipartFile[] folder) {
        	// 指定存放目录
            boolean b = FilesUtil.saveFiles("D:/upload", folder);
            if (b)
                return ResultUtil.success("上传成功");
            else
                return ResultUtil.error("有至少一个文件上传失败");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    FilesUtil

    public class FilesUtil {
    
        public static boolean saveFiles(String savePath, MultipartFile[] files) {
            // 检查文件数组是否为空或长度为0,如果是则直接返回false
            if (files == null || files.length == 0) {
                return false;
            }
    
            // 如果savePath以"/"结尾,去掉末尾的"/"
            if (savePath.endsWith("/")) {
                savePath = savePath.substring(0, savePath.length() - 1);
            }
    
            boolean allFilesSaved = true; // 用于记录所有文件是否都保存成功
    
            // 遍历文件数组,保存每个文件
            for (MultipartFile file : files) {
                // 构建文件的完整路径
                String filePath = savePath + "/" + file.getOriginalFilename();
                // 确保目录存在,不存在则创建
                makeDir(filePath);
    
                // 创建文件对象并保存文件
                File dest = new File(filePath);
                try {
                    file.transferTo(dest);
                } catch (IllegalStateException | IOException e) {
                    // 记录异常信息,可以考虑使用日志框架
                    System.err.println("Failed to save file: " + file.getOriginalFilename());
                    e.printStackTrace();
                    allFilesSaved = false; // 标记为有文件保存失败
                }
            }
    
            return allFilesSaved; // 返回是否所有文件都保存成功
        }
    
        private static void makeDir(String filePath) {
            // 如果filePath中含有"/",则获取目录路径
            int lastIndex = filePath.lastIndexOf('/');
            if (lastIndex > 0) {
                String dirPath = filePath.substring(0, lastIndex);
                File dir = new File(dirPath);
                // 如果目录不存在,则创建目录
                if (!dir.exists() && !dir.mkdirs()) {
                    System.err.println("Failed to create directory: " + dirPath);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 相关阅读:
    shap库源码和代码实现
    MySQL 执行计划参数
    GitHub上标星120k的Java进阶面试教程等!(建议收藏)
    使用Android辅助功能AccessibilityService实现微信自动聊天【外挂插件】
    怎样判定一个可执行文件是否是PIE 格式的文件
    登录功能和退出功能(瑞吉外卖)
    [git] 如何克隆仓库,进行项目撰写,并绑定自己的远程仓库
    【路径规划】基于梯度下降算法求解自定义起点终点障碍路径规划问题附matlab代码
    vscode 连接 GitHub
    代码随想录算法训练营 动态规划part13
  • 原文地址:https://blog.csdn.net/qq_51137480/article/details/137964478