web上传zip大文件,java服务接收并解压ZIP文件

Java压缩与解压缩ZIP文件 小而美的使用JDK自带的ZIP工具包生成与解压缩ZIP文件 阅读详情

目录

一、背景

二、知识点

三、代码实现

1、依赖

2、web 代码

3、 java服务端


一、背景

公司产品小伙伴画了原型后,需要上传到服务器上供开发查看;由于文件数量很多,100M左右差不多要传30分钟,这期间在替换文件导致原型无法正常查看,耽误开发小伙伴时间;随后建议他们将文件压缩为zip压缩包,基本上传也就30秒左右;但是产品小伙伴不会linux命令,也担心他们将服务器弄的“一塌糊涂”,所以就想着做个简单的zip文件上传并自动解压的简单功能。

二、知识点

  • 大文件上传

SpringBoot 项目上传默认单个文件1M,一次上传请求大小10M,上传的文件超过了这个限制就会报错。

如果上传的文件不是特别大,或者在内网上传,那么就直接修改这个配置即可,web端和服务端开发都会比较简单(本文就是采用这个方式)。但是缺点就是上传时间可能比较长,如果设置了超时,会存在上传超时。

application.yml 配置:

spring:
  servlet:
    multipart:
      # 配置 -1 为无限制
      max-file-size: 100MB
      max-request-size: 100MB

如果上传的文件特别大,并且希望快速上传,可以使用百度的 WebUploader JS 插件对文件进行分片上传,服务端顺序写入到文件中。这个功能可以后续写篇博文。

  • zip文件保存

Spring 框架做文件上传,都是封装到 MultipartFile 对象中的。保存到文件最简单的就是使用 MultipartFile.transferTo(file) 方法。

当然也可以自己拿到文件流读取然后写入到zip文件中,注意,一定要用Zip流操作,用普通的流写的zip不可用。

  • 解压zip文件

使用 zip4j 工具包,解压超级简单,2行代码就搞定了。

  • Jquery ajax 上传文件

不使用 form 表单上传,而是使用 ajax 上传,就不用做两个页面了。ajax 上传文件就需要使用内置的 FormData 对象来作为数据体对象,完成文件的上传。

三、代码实现

1、依赖

<!-- spring boot 父包 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.2.RELEASE</version>
    <relativePath/>
</parent>

<!-- 项目依赖 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>2.9.1</version>
        </dependency>
    </dependencies>

application.yml 配置见上方。 

2、web 代码

index.html 代码,省略不重要的标签,节约篇幅

<!-- Bootstrap 和 treeview CSS 文件 -->
<link rel="stylesheet" href="libs/bootstrap.min.css">
<link rel="stylesheet" href="libs/bootstrap-treeview.min.css">
<!-- body -->
<div class="container">
    <h2>原型部署工具</h2>
    <div>说明:1、选择要部署的路径;2、选择部署的zip文件;3、点击部署</div>
    <br>
    <br>
    <div class="row">
        <div class="col-md-8">
            <div>
                <div class="form-group">
                    <label for="tree">部署路径</label>
                    <div id="tree"></div>
                </div>
                <div class="form-group">
                    <label for="file">zip文件</label>
                    <input type="file" id="file" accept=".zip" required>
                    <p class="help-block">仅支持zip文件,且不超过100MB</p>
                </div>
                <button type="button" class="btn btn-default" id="bt" disabled="disabled" onclick="deploy()">提交</button>
            </div>
        </div>
    </div>
</div>
<!-- js 依赖 -->
<script src="libs/jquery-3.6.0.min.js"></script>
<script src="libs/bootstrap.min.js"></script>
<script src="libs/bootstrap-treeview.min.js"></script>
<script src="index.js"></script>

index.js 简略版

var $tree = $('#tree');
var $file = $('#file');
// 用于校验的字段
var deployPath;
var filename;
// 加载可部署的目录树
$.ajax({
    url: "deploy/path/tree",
    type: "get",
    success: function (data) {
        $tree.treeview({
            data: [data],
            onNodeSelected: function (event, data) { // 选择树节点事件
                deployPath = data.path;
                $("button").removeAttr("disabled");
            }
        });
    },
    error: function (err) {
        console.error(err);
        alert("加载部署路径 tree 错误");
    }
});

$file.on("change", function () { // 文件选择事件
    filename = $file.val();
});
// 上传文件
function deploy() {
    // 校验字段省略
    // 使用 ajax 上传文件,需要用 FormData 对象
    var formData = new FormData();
    formData.append("path", deployPath);
    formData.append("file", $file[0].files[0]); // 要上传的文件
    $.ajax({
        url: "deploy/upload",
        type: "post",
        data: formData,
        contentType: false,
        processData: false,
        success: function (data) {
            console.log("部署完成");
        },
        error: function (err) {
            console.error(err);
        }
    });
}

3、 java服务端代码

Controller 代码(省略部分不重要的代码)

package com.chc.yx.deploy.web;

import com.chc.yx.deploy.bean.PathResult;
import com.chc.yx.deploy.bean.UploadFile;
import net.lingala.zip4j.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;

/**
 * 部署控制器
 *
 * @author chc
 * @date 2021/12/31
 * @since 1.0
 */
@RestController
@RequestMapping("/deploy")
public class DeployController implements InitializingBean {

    private Logger log = LoggerFactory.getLogger(getClass());
    // 部署基础路径,只能部署在这个目录及其子目录下
    @Value("${deploy.basePath}")
    private String basePath;
    // 解压的编码:解决linux中文乱码
    @Value("${deploy.charset}")
    private String charset;

    /**
     * 读取指定目录下的所有子目录路径名称
     */
    @GetMapping("/path/tree")
    public ResponseEntity<PathResult> pathTree() {
        Path path = Paths.get(basePath);
        // ...省略代码:递归扫描basePath路径下的子目录,以对应的层级封装到PathResult中,供treeview显示可以部署的路径...
        return ResponseEntity.ok(pathResult);
    }

    /**
     * 上传文件
     * @param UploadFile 自定义的参数类
     */
    @PostMapping("/upload")
    public ResponseEntity upload(UploadFile uploadFile) {
        // 部署的路径
        String path = uploadFile.getPath();
        MultipartFile file = uploadFile.getFile();
        // zip文件名称
        String originalFilename = file.getOriginalFilename();
        log.info("部署信息:path = {}, name = {}", path, originalFilename);
        Path zipFilePath = Paths.get(path, originalFilename);
        // ... 省略代码:删除历史同名 zip 文件 ...
        
        try {
            // 使用 MultipartFile.transferTo 保存zip文件
            file.transferTo(zipFilePath);
            log.info("保存{}成功", originalFilename);
        } catch (IOException e) {
            log.error("保存" + zipFilePath + "错误", e);
            return ResponseEntity.status(500).body("保存" + zipFilePath + "错误");
        }

        // 删除非压缩文件
        String targetFilename=originalFilename.substring(0,originalFilename.length()-4);
        Path filePath = Paths.get(path, targetFilename);
        if (Files.exists(filePath)) {
            AtomicBoolean result = new AtomicBoolean(true);
            deleteDirectoryAll(filePath, result);
            log.info("删除{}下的文件结果:{}", targetFilename, result.get());
        }

        // 使用 zip4j 解压:首先指定 zip 文件
        try (ZipFile zipFile = new ZipFile(zipFilePath.toString())) {
            // 指定编码集,主要是解决linux系统上中文乱码
            zipFile.setCharset(Charset.forName(charset));
            // 指定要解压到的目录下,并解压
            zipFile.extractAll(filePath.getParent().toString());
            log.info("解压{}成功", originalFilename);
        } catch (IOException e) {
            log.error("解压zip错误", e);
            return ResponseEntity.status(500).body("解压zip文件错误");
        }

        // 删除zip文件
        try {
            Files.delete(zipFilePath);
        } catch (IOException e) {
            log.info("删除{}成功", originalFilename);
        }
        log.info("部署完成");
        return ResponseEntity.ok("success");
    }

    /**
     * 递归删除目录和下面的文件————java api删除目录的话,目录必须是空的才能删除
     */
    private void deleteDirectoryAll(Path path, final AtomicBoolean result) {
        try (Stream<Path> stream = Files.list(path)) {
            stream.forEach(p -> {
                if (Files.isDirectory(p)) {
                    deleteDirectoryAll(p, result);
                }
                try {
                    Files.delete(p);
                } catch (IOException e) {
                    log.error("删除文件错误", e);
                    result.set(false);
                }
            });
        } catch (IOException e) {
            log.error("list path error", e);
            result.set(false);
        }
    }

}

上面Controller中提供了两个配置参数:

1、deploy.basePath 用于指定可以部署的根目录

2、deploy.charset 用于指定解码的字符集,主要是用于解决 linux 系统上中文文件名的乱码问题的;在linux上如果使用 UTF-8 解码存在中文乱码,则可以使用 CP936 编码。

Java 上传解压zip文件,并且解析文件里面的exc... PS:为了方便不同水平的开发人员阅读,我把代码全部写到Controller里面。这个demo的file入参的类型是MultipartFile,很多网上的例子是File类型。这两个类型在解析文件的时候还是有点区别的。 第①个方法: [url=][/url]1 /**2 * 这个deomo入参的类型是MultipartFile,很多网上的例子是File类型3 *@... 阅读详情

相关推荐

Java实现minio文件服务web在线解压上传工具类

commons-compress是Apache Commons项目的一个子项目,它提供了用于处理压缩和解压缩文件的Java库。MinIO是一个开源的云存储服务器,它兼容Amazon S3 API,并提供了高性能、可扩展和分布式的对象存储解决方案。

洛阳泰山的博客 5859

Java 导入zip,并进行解压

Java 导入zip,并进行解压 场景一:上传zip包,后台进行解压,提取里面的文件,进行上传。 场景二:上传zip,后台进行解压,提取zip包中“文件夹”以及该“文件夹”下的文件后,再进行压缩上传。

ding43930053的专栏 8362

Graylog日志系统实战:高效接收与解析交换机日志

本文提供Graylog日志系统的实战部署与配置指南,重点讲解如何高效接收与解析交换机日志。通过Docker快速部署,配置Syslog输入,并指导华为、华三等主流交换机将日志发送至Graylog。文章还介绍了使用提取器解析日志字段、创建数据流进行分类,以及设置报警规则,实现从被动排查到主动预警的运维转变,帮助网络工程师构建集中、智能的日志管理系统。

weixin_29284885的博客 540

java上传zip文件并解压读取

最近遇到一个这样的需求:传一个压缩包给后台,后台保存后解压读取里面的文件,现学现做。在这里做个记录 文件上传 文件上传有很多方法,这里推荐一个自己感觉挺好用的一种,代码奉上: @PostMapping(value = "/import", headers = "content-type=multipart/*") public R importSqlLite(@RequestParam...

梓隽的博客 2万+

Leaflet 加载天地图完整配置指南:从插件修改到无限缩放(附源码)

本文详细介绍了Leaflet与天地图深度集成的完整配置指南,包括插件修改、无限缩放实现及源码示例。通过解析天地图服务的WMTS协议、双投影支持和密钥机制,帮助开发者突破缩放级别限制,优化地图应用性能,适用于Web地图开发和高精度GIS系统。

weixin_27180827的博客 441

Windows平台无人机仿真:从零搭建SITL环境与QGC联调

本文详细指导了在Windows平台上从零搭建无人机软件在环(SITL)仿真环境,并与QGroundControl(QGC)进行联调的完整流程。通过使用Cygwin工具链,开发者可以在没有实体硬件的情况下,模拟运行ArduPilot飞控,并通过MAVLink协议连接QGC地面站进行全功能测试,为无人机软件开发提供了一个安全、经济的虚拟沙盒环境。

weixin_29239279的博客 411

(总目录)springboot - 实现zip文件上传并对zip文件解压, 包含上传oss

java 文件校验文件 上传文件 压缩zip文件的解压 oss的文件上传 oss前端上传 解决方法加charset(utf-8) 不行windows换gbk注意文件夹路径对应, 解压文件路径, 包括文件路径斜线问题\\和流用完记得关闭判断是否为空 避免空指针。

pingzhuyan的博客 4248

MATLAB与图像处理(一):图像中结构张量的求法(Structure Tensor)

1.结构张量的作用:       能够区分图像中的平坦区域,边缘,角点; 2.图像中的结构张量的定义    1)是一个矩阵;    2)与图像的水平,垂直梯度有关,定义如下: 在MATLAB中,可以用如下语句求解:[Ix,Iy]=gradient(Image); 3)求出结构张量矩阵的行列式,和迹(矩阵对角线之和)   行列式:K=det(E);   迹:  

wenyusuran的专栏 5242

java web上传压缩包_通过WebUpload上传zip文件并解压(用于批量上传照片等)

前端htmltip:请将照片统一命名为“学号+后缀名”(如16032051.jpg),照片格式为JPG/JPEG,将所有照片直接压缩打包zip文件后再上传。选择文件开始上传jsvar uploader = WebUploader.create({// 文件接收服务端。server: '/user/uploadPhoto',// 选择文件的按钮。可选。// 内部根据当前运行是创建,可能是input元...

weixin_42514005的博客 1488

OpenCV C++ 图像处理实战 ——《基于轮廓比对的缺陷检测》

本文使用OpenCV C++ 实现基于轮廓比对的缺陷检测。

Zero___Chen的博客 1149

196、NPU的编译器开发:教程与示例代码编写

NPU编译器开发实战指南 摘要:本文分享了NPU编译器开发中的核心挑战与实战经验,通过具体代码示例展示了关键实现技术: 指令生成:必须考虑硬件特性(如地址对齐)和芯片配置抽象化 图优化:重点处理常见冗余结构(Reshape合并、BN融合),并注意数值稳定性 算子拆分:采用分块计算策略适配有限SRAM,需特别注意边界条件处理 内存分配:基于张量使用频率的贪心算法优化SRAM使用效率 文中包含多个真实踩坑案例: DMA地址未对齐导致硬件错误 BN融合时的除零风险 tile边界处理不当引起的精度下降 这些经验为开

m0_50546716的博客 88

springboot 上传zip包,并解压 至 服务器nginx目录

前言:此案例场景为:从前端上传.zip 包,并进行解压至 docker容器内(服务部署使用了docker),然后容器内部解压目录与 宿主机(linux)nginx 目录的html 进行挂载,这样,就可以通过nginx 来访问上传解压出来的文件了, 那么具体看怎么实现,下面会贴上相关代码 1.首先需要引入zip相关jar包 <dependency> <groupId>net.lingala.zip4j</groupId>

qq_42962779的博客 3960

《C/C++等级考试(1~8级)历届真题解析》专栏总目录

中国电子学会《全国青少年软件编程等级考试》C/C++编程(1~8级)历届真题解析。订阅后可阅读专栏内所有真题解析,真题持续更新中!

人生就是一个不断学习的过程 2万+

Java文件file上传到服务器并读取指定目录下文件(含解压缩)

Java读取上传文件,并保存到服务器,并在服务器端进行解压缩: package com.msunsoft.common.upload.service; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java...

sinat_25311845的博客 1万+

STM32F407最小系统硬件设计与CubeMX工程实践

嵌入式最小系统是MCU功能实现的物理基础,其核心涵盖供电网络、时钟架构、复位机制与调试接口四大模块。基于Cortex-M4内核的STM32F407对电源纹波、晶振稳定性及信号完整性提出严苛要求:模拟电源VDDA需<10mV纹波,HSE晶振布线须满足短距直连与匹配电容精准配置,SWD调试接口依赖50Ω阻抗控制与端接防护。这些硬件约束直接映射至STM32CubeMX配置——如RCC时钟树参数必须与实物晶振频率严格一致,GPIO模式需匹配外设电气特性(如I2C必选开漏),否则将引发通信失败或启动异常。典型应用场景

weixin_35592186的博客 173

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

java上传zip_JAVA 上传ZIP,RAR文件并解压

【实例简介】java上传文件 实时获取上传进度 上传RAR,ZIP 并指定解压路劲 上传之后会按照路劲进行解压【实例截图】【核心代码】MyUpload└── MyUpload├── ROOT│ ├── index.jsp│ ├── js│ │ ├── jquery-1.7.2.js│ │ └── jquery-1.7.2.min.js│ ├── META-INF│ ...

weixin_39816141的博客 1249

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SpringMvc 实现上传zip文件解压

去掉了一些敏感数据,仅供参考 import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Invoca...

u012798049的博客 2580

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Spring Boot文件处理实战:从ZIP解压到图片信息识别

Spring Boot文件处理实战摘要 本文介绍了基于Spring Boot的文件处理工具开发,主要功能包括ZIP文件解压、图片OCR识别和Excel导出。技术方案采用Spring Boot+Thymeleaf实现前后端交互,运用Apache POI处理Excel,通过百度OCR API识别图片信息。文章详细讲解了文件上传接口设计、ZIP解压安全处理、OCR信息提取等核心功能实现,并提供了防止ZIP滑动攻击等安全措施。项目亮点在于将复杂文件处理流程模块化,从上传到结果生成一站式解决,同时保留服务器副本。适合

私聊前往站内信:https://i.youkuaiyun.com/#/msg/chat/weixin_44976692 1829

java zip上传_Java 上传解压zip文件,并且解析文件里面的excel和图片

1 import java.io.*;2 importjava.nio.channels.FileChannel;3 importjava.nio.file.Files;4 importjava.nio.file.Path;5 importjava.nio.file.Paths;6 importjava.nio.file.attribute.PosixFilePermission;7 import...

weixin_29761519的博客 1228

Java 文件解压处理Zip,7z,Rar

package com.web.framework.slms.module.work; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.Ra..

weixin_44005694的博客 2433

【已解决】Java zip解压时候 malformed input off : 4, length : 1

的格式不正确或损坏。如果在Java中解压文件时报错 “malformed”,通常表示。我试了集中方法都不行,最后看有人说是。,加上GBK编码格式后解析成功。将上传文件上传到服务器上。ZipUtils代码类。对zip文件进行解压。

凯哥Java的博客 3687

java上传并解压文件

我整理的一些关于【Java】的项目学习资料(附讲解~~)和大家一起分享、学习一下:https://d.51cto.com/bLN8S1Java 上传并解压文件指南 在今天的技术环境中,文件上传和处理是Web应用中的常见需求。本文将指导你如何在Java中实现文件上传并解压缩的功能。我们将按照一定的步骤进行。以下是实现的整体...

weixin_36579440的博客 237

java 解压zip文件

首先当如jar包ant 这边以1.7.0做测试 <!--zip--> <dependency> <groupId>ant</groupId> <artifactId>ant</artifactId> <version>1.7.0</version> </dependency> public static String unZipFiles(MultipartFile mfile).

weixin_42461205的博客 388
下一篇: Java实现darknet+yolov4的目标检测
网上搬砖
博客等级 码龄6年 4粉丝 9原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值