java文件夹上传,保留文件夹结构

需求: 产品要求可以上传文件夹,文件夹下包含其他文件夹

前端上传文件夹,可以把文件以及所在文件所在文件夹信息传到后端

1.前端设置

需要设置 webkitdirectory enctype = multipart/form-data

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件夹上传</title>
</head>
<body>
<form action="/file/folderUpload" method="post" enctype="multipart/form-data">
    <input type="file" name="multipartFiles" multiple webkitdirectory>
    <button type="submit">上传</button>
</form>
</body>
</html>

2.后端代码

service impl 代码

import cn.hutool.core.util.StrUtil;
import com.example.folder.upload.entity.TreeNodeDTO;
import com.example.folder.upload.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FileServiceImpl implements FileService {
    /**
     * 文件夹上传
     *
     * @param files
     */
    public List<TreeNodeDTO> folderUpload(MultipartFile[] files) {
        List<TreeNodeDTO> treeNodeDTOList = new ArrayList<>();
        if (files == null || files.length == 0) {
            return new ArrayList<>();
        }
        String firstFolder = null;
        for (MultipartFile file : files) {
            TreeNodeDTO treeNodeDTO = new TreeNodeDTO();
            String filePath = file.getOriginalFilename();
            if (filePath.lastIndexOf(StrUtil.C_SLASH) > 0) {
                String dirPath = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(StrUtil.C_SLASH));
                // 设置文件所在目录的全目录路径
                treeNodeDTO.setFolderFullName(dirPath);
                String[] split = dirPath.split(StrUtil.SLASH);
                if (split != null) {
                    String folder = split[split.length - 1];
                    // 文件所在当前目录名称
                    treeNodeDTO.setFolderName(folder);
                }
                if (firstFolder == null) {
                    firstFolder = split[0];
                }
            }
            int index = filePath.lastIndexOf(StrUtil.C_SLASH);
            String fileName = filePath.substring(index + 1);
            // 文件名称
            treeNodeDTO.setName(fileName);
            treeNodeDTOList.add(treeNodeDTO);
        }
        // 判断是否存在一级目录
        List<String> fullFolderList = treeNodeDTOList.stream().map(TreeNodeDTO::getFolderFullName).collect(Collectors.toList());
        if (firstFolder != null && !fullFolderList.contains(firstFolder)) {
            TreeNodeDTO treeNodeDTO = new TreeNodeDTO();
            treeNodeDTO.setFolderName(firstFolder);
            treeNodeDTO.setFolderFullName(firstFolder);
            treeNodeDTOList.add(treeNodeDTO);
        }
        treeNodeDTOList.forEach(treeNodeDTO -> {
            log.info("文件名:{},目录全路径:{},当前目录:{}",treeNodeDTO.getName(),treeNodeDTO.getFolderFullName(),treeNodeDTO.getFolderName());
        });
        return treeNodeDTOList;
    }

}

service 代码

import com.example.folder.upload.entity.TreeNodeDTO;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public interface FileService {
    /**
     * 文件夹上传
     * @param files
     */
    List<TreeNodeDTO> folderUpload(MultipartFile[] files);
}

3.controller

import com.example.folder.upload.entity.TreeNodeDTO;
import com.example.folder.upload.service.FileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/file")
public class FileController {
    @Resource
    private FileService fileService;

    @RequestMapping(value = "/folderUpload", method = RequestMethod.POST)
    public List<TreeNodeDTO> uploadFolder(MultipartFile[] multipartFiles) {
        return fileService.folderUpload(multipartFiles);
    }
}

4. treeNodeDTO 

import lombok.Data;

@Data
public class TreeNodeDTO {
    /**
     * 文件名
     */
    private String name;
    /**
     * 最后一级文件夹名称
     */
    private String folderName;
    /**
     * 全路径文件夹
     */
    private String folderFullName;
}

5.效果图

 6. github代码地址

GitHub - katriina-tavi/folder-upload: 文件夹上传

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/35298.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

应用层:动态主机配置协议(DHCP)

1.应用层&#xff1a;动态主机配置协议(DHCP) 笔记来源&#xff1a; 湖科大教书匠&#xff1a;应用层概述 湖科大教书匠&#xff1a;动态主机配置协议(DHCP) 声明&#xff1a;该学习笔记来自湖科大教书匠&#xff0c;笔记仅做学习参考 如何配置用户主机才能使用户主机正常访问…

【数据科学赛】2023大模型应用创新挑战赛 #¥10万 #百度

CompHub 主页增加了“近两周上新的奖金赛”&#xff0c;更加方便查找最新比赛&#xff0c;欢迎访问和反馈&#xff01; 以下内容摘自比赛主页&#xff08;点击文末阅读原文进入&#xff09; Part1赛题介绍 题目 2023大模型应用创新挑战赛 举办平台 Baidu AI Studio 主办方…

Java设计模式之一:观察者模式

目录 一、什么是观察者模式 二、如何使用观察者模式 三、观察者模式的优势和使用场景 一、什么是观察者模式 观察者模式是一种常见的设计模式&#xff0c;用于在对象之间建立一对多的依赖关系。在该模式中&#xff0c;一个主题&#xff08;被观察者&#xff09;维护了一个观…

力扣 93. 复原 IP 地址

题目来源&#xff1a;https://leetcode.cn/problems/restore-ip-addresses/description/ C题解&#xff1a;递归回溯法。 递归参数&#xff1a;因为不能重复分割&#xff0c;需要ind记录下一层递归分割的起始位置&#xff1b;还需要一个变量num&#xff0c;记录ip段的数量。递…

陪诊小程序系统|陪诊软件开发|陪诊系统功能和特点

随着医疗服务的逐步改善和完善&#xff0c;越来越多的人群开始走向医院就诊&#xff0c;而其中不少人往往需要有人陪同前往&#xff0c;这就导致了许多矛盾与问题的发生&#xff0c;比如长时间等待、找不到合适的陪诊人员等。因此为人们提供一种方便快捷的陪诊服务成为了一种新…

【实战】 二、React 与 Hook 应用:实现项目列表 —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表1.新建文件2.状态提升3.新建utils4.Custom Hook 学习内容来源&#xff1a;React React Hook TS 最佳实践-慕课网 相对原教程&#xff0c;我在学习开始时&#xff08;2023.0…

ClickHouse主键索引最佳实践

在本文中&#xff0c;我们将深入研究ClickHouse索引。我们将对此进行详细说明和讨论&#xff1a; ClickHouse的索引与传统的关系数据库有何不同ClickHouse是怎样构建和使用主键稀疏索引的ClickHouse索引的最佳实践 您可以选择在自己的机器上执行本文给出的所有Clickhouse SQL…

SQlite数据库

SQlite数据库 1.SQLite简介 轻量化&#xff0c;易用的嵌入式数据库&#xff0c;用于设备端的数据管理&#xff0c;可以理解成单点的数据库。传统服务器型数据库用于管理多端设备&#xff0c;更加复杂 SQLite是一个无服务器的数据库&#xff0c;是自包含的。这也称为嵌入式数…

2020年国赛高教杯数学建模C题中小微企业的信贷决策解题全过程文档及程序

2020年国赛高教杯数学建模 C题 中小微企业的信贷决策 原题再现 在实际中&#xff0c;由于中小微企业规模相对较小&#xff0c;也缺少抵押资产&#xff0c;因此银行通常是依据信贷政策、企业的交易票据信息和上下游企业的影响力&#xff0c;向实力强、供求关系稳定的企业提供贷…

Win10电脑开机PIN码怎么取消?

有的用户稀里糊涂的设置了PIN码之后&#xff0c;在开机时发现多了个PIN码&#xff0c;但又不知道电脑PIN码是什么意思&#xff0c;也不清楚开机PIN码怎么取消。您可以通过阅读以下内容&#xff0c;以了解什么是PIN以及如何取消PIN码。 PIN码是一种快捷登录密码方式&#xff0c;…

lesson 12 Zigbee绑定通信

目录 Zigbee绑定通信 通信原理 实验过程 实现步骤 实验现象 实验分析 Zigbee绑定通信 通信原理 1、Zigbee一共有五种通信方式&#xff1a;单播、广播、组播、MAC、广播 2、绑定是Zigbee的一种基本通信方式&#xff0c;具体绑定通信又分为三种模式&#xff0c;模式大同…

java 计算网段范围 分析网段包含关系

目录 一、网段范围 二、思路说明 三、代码 1、将一个ip转为数字 2、转换子网掩码&#xff08;255.255.255.0 转为 24&#xff09; 3、根据 ip 与 掩码 计算最大值和最小值 4、测试 5、完整代码 四、难点讲解 1、转换子网掩码&#xff0c; 例&#xff1a;255.255.25…

数据总线学习

为啥要数据总线 使用服务化方式发布&#xff0c;业务端和中间件完全解耦合。一处生产&#xff0c;处处消费设计理念。提供用户可定制的托管化通用消费方案&#xff08;如同步mysql到缓存&#xff0c;同步mysql到es&#xff0c;消费mysql到大数据等托管服务&#xff09; 特性 …

RabbitMQ系列(18)--RabbitMQ基于插件实现延迟队列

1、前往RabbitMQ官网下载往RabbitMQ添加延迟消息的插件 RabbitMQ官网下载插件的网址&#xff1a;https://www.rabbitmq.com/community-plugins.html 2、下载rabbitmq_delayer_message_exchange插件&#xff08;注&#xff1a;RabbitMQ是什么版本的&#xff0c;下载的插件就得是…

【UE5 Cesium】12-Cesium for Unreal 去除左下角的icon

问题 在视口左下角的icon如何去除&#xff1f; 解决方法 打开“CesiumCreditSystemBP” 将“Credit Widget Class”一项中的“ScreenCredit”替换为“ScreenCreditWidget” 编译之后icon就不显示了。

2023年5月PETS5(WSK)考试经验分享

由于本人明年打算出国联培的缘故&#xff0c;CSC国家留学基金委需要申请人的语言成绩达到一定的要求 英语&#xff08;PETS5&#xff09;&#xff1a;笔试总分55分&#xff08;含&#xff09;以上&#xff0c;其中听力部分18分&#xff08;含&#xff09;以上&#xff0c;口试…

2023最新AI创作系统/ChatGPT商业运营版网站程序源码+支持GPT4+支持ai绘画(MJ)+实时语音识别输入+免费更新版本

2023最新AI创作系统/ChatGPT商业运营版网站程序源码支持ai绘画支持GPT4.0实时语音识别输入文章资讯发布功能用户会员套餐免费更新版本 一、AI创作系统二、系统介绍三、系统程序下载四、安装教程五、主要功能展示六、更新日志 一、AI创作系统 1、提问&#xff1a;程序已经支持G…

“生鲜蔬”APP的设计与实现

1.引言 在这个科技与网络齐头并进的时代&#xff0c;外卖服务正在飞速发展&#xff0c;人们对外卖APP系统功能需求越来越多&#xff0c;开发APP的人员对自己的要求也要越来越高&#xff0c;要从所做APP外卖系统所实现的功能和用户的需求来对系统进行设计&#xff0c;还需要与当…

2023年船舶、海洋与海事工程国际会议(NAOME 2023) | Ei Scopus双检索

会议简介 Brief Introduction 2023年船舶、海洋与海事工程国际会议(NAOME 2023) 会议时间&#xff1a;2023年10月20日-22日 召开地点&#xff1a;中国镇江 大会官网&#xff1a;NAOME 2023-2023 International Conference on Naval Architecture and Ocean & Marine Engine…

腾讯云对象存储联合DataBend云数仓打通数据湖和数据仓库

随着数字化进程不断深入&#xff0c;数据呈大规模、多样性的爆发式增长。为满足更多样、更复杂的业务数据处理分析的诉求&#xff0c;湖仓一体应运而生。在Gartner发布的《Hype Cycle for Data Management 2021》中&#xff0c;湖仓一体&#xff08;Lake house&#xff09;首次…
最新文章