java实现上传zip/rar压缩文件,自动解压

在pom中添加解压jar依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hf</groupId>
    <artifactId>uncompress</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>uncompress</name>
    <description>上传压缩文件(rar或者zip格式),解压</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--
        从Zip文件创建,添加,提取,更新,删除文件
        读/写密码保护的Zip文件
        支持AES 128/256加密
        支持标准邮​​编加密
        支持Zip64格式
        支持存储(无压缩)和Deflate压缩方法
        从Split Zip文件创建或提取文件(例如:z01,z02,... zip)
        支持Unicode文件名
        进度监视器
        -->
        <!--zip4j依赖,解压zip压缩-->
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--解压rar压缩-->
        <dependency>
            <groupId>com.github.junrar</groupId>
            <artifactId>junrar</artifactId>
            <version>0.7</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

解压zip/rar的工具类

package com.hf.uncompress.utils;

import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;

import java.io.File;
import java.io.FileOutputStream;

/**
 * @Description: 解压rar/zip工具类
 * @Date: 2019/1/22
 * @Auther:
 */
@Slf4j
public class UnPackeUtil {

    /**
     * zip文件解压
     *
     * @param destPath 解压文件路径
     * @param zipFile  压缩文件
     * @param password 解压密码(如果有)
     */
    public static void unPackZip(File zipFile, String password, String destPath) {
        try {
            ZipFile zip = new ZipFile(zipFile);
            /*zip4j默认用GBK编码去解压,这里设置编码为GBK的*/
            zip.setFileNameCharset("GBK");
            log.info("begin unpack zip file....");
            zip.extractAll(destPath);
            // 如果解压需要密码
            if (zip.isEncrypted()) {
                zip.setPassword(password);
            }
        } catch (Exception e) {
            log.error("unPack zip file to " + destPath + " fail ....", e.getMessage(), e);
        }
    }

    /**
     * rar文件解压(不支持有密码的压缩包)
     *
     * @param rarFile  rar压缩包
     * @param destPath 解压保存路径
     */
    public static void unPackRar(File rarFile, String destPath) {
        try (Archive archive = new Archive(rarFile)) {
            if (null != archive) {
                FileHeader fileHeader = archive.nextFileHeader();
                File file = null;
                while (null != fileHeader) {
                    // 防止文件名中文乱码问题的处理
                    String fileName = fileHeader.getFileNameW().isEmpty() ? fileHeader.getFileNameString() : fileHeader.getFileNameW();
                    if (fileHeader.isDirectory()) {
                        //是文件夹
                        file = new File(destPath + File.separator + fileName);
                        file.mkdirs();
                    } else {
                        //不是文件夹
                        file = new File(destPath + File.separator + fileName.trim());
                        if (!file.exists()) {
                            if (!file.getParentFile().exists()) {
                                // 相对路径可能多级,可能需要创建父目录.
                                file.getParentFile().mkdirs();
                            }
                            file.createNewFile();
                        }
                        FileOutputStream os = new FileOutputStream(file);
                        archive.extractFile(fileHeader, os);
                        os.close();
                    }
                    fileHeader = archive.nextFileHeader();
                }
            }
        } catch (Exception e) {
            log.error("unpack rar file fail....", e.getMessage(), e);
        }
    }
}

页面HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="./jquery-3.2.1.min.js" type="text/javascript"></script>
    <!--<script type="text/javascript">
        $("#ok").click(function () {
            alert(1);
        });
    </script>-->
</head>
<body>
<form action="/user/upload/zip" method="post" enctype="multipart/form-data">
    上传压缩包:<input type="file" name="zipFile"/>
    解压路径:<input type="text" name="destPath"/>
    解压密码(为空可不传):<input type="text" name="password"/></br>
    <button id="ok" value="测试"></button>

    <input type="submit" value="执行操作"/>
</form>
</body>

</html>

controller代码:

package com.hf.uncompress.controller;

import com.hf.uncompress.Result.AjaxList;
import com.hf.uncompress.service.FileUploadService;
import com.hf.uncompress.vo.PackParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Description:
 * @Date: 2019/1/22
 * @Auther: 
 */

@Controller
@RequestMapping("/user")
@Slf4j
public class FileUploadController {

    @Autowired
    private FileUploadService fileUploadService;

    @GetMapping("/redirect")
    public String redirectHtml() {
        return "work";
    }

    @PostMapping("/upload/zip")
    @ResponseBody
    public String uploadZip(MultipartFile zipFile, @RequestBody PackParam packParam) {
        AjaxList<String> ajaxList = fileUploadService.handlerUpload(zipFile, packParam);
        return ajaxList.getData();
    }
}

service实现类代码

package com.hf.uncompress.service.impl;

import com.hf.uncompress.Result.AjaxList;
import com.hf.uncompress.enums.FileTypeEnum;
import com.hf.uncompress.service.FileUploadService;
import com.hf.uncompress.utils.UnPackeUtil;
import com.hf.uncompress.vo.PackParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * @Description:
 * @Date: 2019/1/22
 * @Auther: 
 */
@Service
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {

    @Override
    public AjaxList<String> handlerUpload(MultipartFile zipFile, PackParam packParam) {

        if (null == zipFile) {
            return AjaxList.createFail("请上传压缩文件!");
        }
        boolean isZipPack = true;
        String fileContentType = zipFile.getContentType();
        //将压缩包保存在指定路径
        String packFilePath = packParam.getDestPath() + File.separator + zipFile.getName();
        if (FileTypeEnum.FILE_TYPE_ZIP.type.equals(fileContentType)) {
            //zip解压缩处理
            packFilePath += FileTypeEnum.FILE_TYPE_ZIP.fileStufix;
        } else if (FileTypeEnum.FILE_TYPE_RAR.type.equals(fileContentType)) {
            //rar解压缩处理
            packFilePath += FileTypeEnum.FILE_TYPE_RAR.fileStufix;
            isZipPack = false;
        } else {
            return AjaxList.createFail("上传的压缩包格式不正确,仅支持rar和zip压缩文件!");
        }
        File file = new File(packFilePath);
        try {
            zipFile.transferTo(file);
        } catch (IOException e) {
            log.error("zip file save to " + packParam.getDestPath() + " error", e.getMessage(), e);
            return AjaxList.createFail("保存压缩文件到:" + packParam.getDestPath() + " 失败!");
        }
        if (isZipPack) {
            //zip压缩包
            UnPackeUtil.unPackZip(file, packParam.getPassword(), packParam.getDestPath());
        } else {
            //rar压缩包
            UnPackeUtil.unPackRar(file, packParam.getDestPath());
        }
        return AjaxList.createSuccess("解压成功");
    }
}

使用到的枚举类:

package com.hf.uncompress.enums;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

/**
 * @Description: 压缩文件类型
 * @Date: 2019/1/22
 * @Auther:
 */
@AllArgsConstructor
@NoArgsConstructor
public enum FileTypeEnum {
    FILE_TYPE_ZIP("application/zip", ".zip"),
    FILE_TYPE_RAR("application/octet-stream", ".rar");
    public String type;
    public String fileStufix;

    public static String getFileStufix(String type) {
        for (FileTypeEnum orderTypeEnum : FileTypeEnum.values()) {
            if (orderTypeEnum.type.equals(type)) {
                return orderTypeEnum.fileStufix;
            }
        }
        return null;
    }
}

同一返回值定义:

package com.hf.uncompress.Result;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Description: 返回值处理
 * @Date: 2019/1/22
 * @Auther: 
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class AjaxList<T> {
    private boolean isSuccess;
    private T data;

    public static <T> AjaxList<T> createSuccess(T data) {
        return new AjaxList<T>(true, data);
    }

    public static <T> AjaxList<T> createFail(T data) {
        return new AjaxList<T>(false, data);
    }
}

前端上传封装的vo

package com.hf.uncompress.vo;

import lombok.Data;

/**
 * @Description: 上传压缩的参数
 * @Date: 2019/1/23
 * @Auther: 
 */
@Data
public class PackParam {
    /**
     * 解压密码
     */
    private String password;

    /**
     * 解压文件存储地址
     */
    private String destPath;
}

在application.properties中定义其上传的阀域

#设置上传单个文件的大小限制
spring.servlet.multipart.max-file-size=500MB
# 上传文件总的最大值
spring.servlet.multipart.max-request-size=500MB
spring.thymeleaf.cache=false

猜你喜欢

转载自blog.csdn.net/qq_42151769/article/details/87270102
今日推荐