Gog_10459 2024-06-26 08:31 采纳率: 0%
浏览 42
已结题

SpringBoot+Vue3

请教一下后端根据前端传入的编号数组然后到指定文件夹找到对应的文件然后压缩成压缩包返回前端下载该怎么写呀。

这里是我的一个后端接口部分代码,然后我想在这里调用比方说一个压缩工具类,压缩指定文件之后返回前端下载。


    // 根据证书编号压缩定义文件返回前端
    @PostMapping("/batch/download")
    public Result batchDownload(String[] certificateNumbers) {
        // 对上传的数据进行校验
        if (certificateNumbers == null || certificateNumbers.length == 0) {
            return Result.error("证书编号不能为空");
        }

        
        return Result.success("文件下载成功");
    }

方法返回类型是我自定义的一个Result类,具体代码如下:


//响应结果封装类
public class Result<T> {

    // 业务状态码 200成功 500失败
    private Integer code;
    // 提示信息
    private String message;
    // 返回响应数据
    private T data;

    // 携带响应数据快速返回成功响应结果
    public static <E> Result<E> success(E data) {
        return new Result<>(200, "操作成功", data);
    }

    // 重载方法 快速返回成功响应结果 无响应数据
    public static Result success() {
        return new Result(200, "操作成功", null);
    }

    // 快速返回失败响应结果
    public static Result error(String message) {
        return new Result(500, message, null);
    }

    // 携带响应数据快速返回失败响应结果 
    public static Result error(String message, Object data) {
        return new Result(500, message, data);
    }

前端部分我写了一个响应拦截器 对应我返回的信息 代码如下:


instance.interceptors.response.use(
    // 当响应成功时触发的回调函数
    result => {

        // 判断业务状态码,通常情况下,200 表示请求成功
        if (result.data.code === 200) {
            // 直接返回响应体中的数据,以便后续的.then链能够继续处理
            return result.data;
        }

        // 如果业务状态码不是200,表示操作失败
        // 错误信息优先使用服务器返回的message,若服务器未提供,则默认提示“服务异常”
        ElMessage.error(result.data.message ? result.data.message : '服务异常');

        // 将Promise状态标记为rejected,使得外部可以统一处理这类失败情况
        return Promise.reject(result.data);
    },

Vue的代码我用的axios我自己写了一个请求工具然后在别的地方调用这个工具



// 导出一个名为exportQrCodeService的异步函数,用于处理导出二维码的请求及文件下载逻辑
export const exportQrCodeService = async (data) => {
    // 发起一个POST请求到'/batch/download'端点,用于下载数据
    // 请求配置包括:
    // - data: 传递给服务器的数据,用于生成或识别要下载的二维码内容
    // - withCredentials: 设置为true,允许跨域请求携带凭证(如cookies)
    // - responseType: 设置响应类型为'blob',这样可以处理二进制数据,适用于文件下载
    return request({
            url: '/batch/download',
            method: 'post',
            data: data,
            withCredentials: true,
            responseType: 'blob',
        })
        // 当请求成功时执行的处理逻辑
        .then((response) => {

            // 打印请求响应
            console.log(response);

            // 使用URL.createObjectURL方法创建一个指向新Blob对象的URL,Blob对象包含了从服务器返回的二进制数据
            const url = window.URL.createObjectURL(new Blob([response.data]));

            // 创建一个新的HTML <a> 元素,用于模拟下载链接
            const link = document.createElement('a');

            // 设置<a>元素的href属性为刚创建的URL,指向要下载的文件数据
            link.href = url;

            // 设置下载属性,指定下载文件的名称为'files.zip'
            link.setAttribute('download', 'files.zip');

            // 将创建的<a>元素临时添加到文档中,以便能触发点击事件
            document.body.appendChild(link);

            // 触发模拟的点击事件,开始下载文件
            link.click();

            // 下载完成后从文档中移除这个临时的<a>元素
            link.remove();
        })
        // 如果请求过程中出现错误,则捕获错误并打印到控制台
        .catch((error) => {
            console.error('Error downloading file:', error);
            // 重新抛出错误,以便在调用此函数的地方可以进一步处理错误
            throw error;
        }) // 添加finally块以确保资源被清理
        .finally(() => {
            // 清理URL对象以释放资源
            window.URL.revokeObjectURL(url);
        });
};

我的代码写的比较烂,如果要改动的话,动的地方有点多,然后这个功能属实是不知道怎么开发了。有劳请基于我给出的代码提供完整解决方案。

  • 写回答

23条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-26 08:31
    关注

    引自免费微信小程序:皆我百晓生

    要解决这个问题,你需要在Spring Boot应用中实现一个后端接口,该接口接受前端发送的一组证书编号,并将这些编号关联到指定的文件夹,然后通过一个压缩工具将这些文件打包成压缩包并返回给前端。这涉及到以下几个步骤:首先,从数据库或其他数据源获取证书编号列表;其次,创建一个文件夹并存放相应的文件;最后,使用一个合适的压缩库(如zip4j)对这些文件进行压缩,并将其打包成一个压缩包。

    以下是实现这一目标的大致步骤:

    1. 构建前端API:确保你的前端API正确地接收来自用户的证书编号数组,并且能有效地传递这些数组到后端。
    2. 配置Spring Boot:在你的Spring Boot项目中,添加必要的依赖项,例如zip4j、spring-boot-starter-data-redis、以及可能需要的其他依赖项。
    3. 编写后端逻辑:在后端路由上添加一个控制器方法,用于处理用户请求并执行上述步骤。这个方法应该接受一个字符串数组作为参数,其中每个元素都是一个证书编号,然后将这些编号与指定文件夹相对应。
    4. 实现文件操作:在方法内部,使用zip4j或类似库来创建一个压缩包,并将包含证书编号的文件放入该包中。确保文件名包括原始证书编号及其扩展名。
    5. 响应格式:返回一个包含压缩包名称和路径的JSON对象,而不是传统的HTTP状态码和消息。

    下面是一个简化的例子,展示如何在一个名为CertificateBatchDownloaderController.java的Java类中实现上述功能:

    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.Arrays;
    import java.util.List;
    import java.util.zip.ZipOutputStream;
    
    public class CertificateBatchDownloaderController {
    
        /**
         * 下载指定证书编号的文件。
         *
         * @param certificateNumbers 需要下载的证书编号数组
         * @return 带有压缩包名称和路径的JSON对象
         */
        @PostMapping("/download/certificates")
        public SseEmitter downloadCertificates(@RequestParam List<String> certificateNumbers) throws IOException {
            // 获取文件夹路径
            Path folderPath = Paths.get("/path/to/your/folder");
    
            // 创建一个ZipOutputStream并初始化
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(folderPath.toFile()));
    
            for (String certificateNumber : certificateNumbers) {
                // 加载文件并放入ZIP
                try (var fileInputStream = Files.newInputStream(Paths.get(certificateNumber))) {
                    byte[] buffer = new byte[8192];
                    int length;
                    while ((length = fileInputStream.read(buffer)) != -1) {
                        zipOut.write(buffer, 0, length);
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
    
            // 关闭ZIP输出流
            zipOut.close();
    
            // 创建一个SSEEmitter并返回其URL
            SseEmitter emitter = new SseEmitter();
            emitter.setUrl("/sse/" + folderPath.toString());
            emitter.onCompletion(() -> System.out.println("SSE connection closed"));
    
            return emitter;
        }
    }
    

    注意:这段代码只是一个基本框架,实际应用中还需要考虑安全性、错误处理、文件权限管理等因素。此外,如果你正在使用的是spring-boot-starter-data-redis,你应该在配置文件中设置正确的Redis客户端ID,以便正确地保存和检索文件。

    在这个例子中,我们创建了一个新的SSEEmitter,它会每隔几秒向客户端发送一条更新消息,指示当前文件是否已经完成压缩。客户端可以通过监听这个SSE连接来实时查看文件压缩进度。

    请记住,这是简化后的示例,实际部署时,你可能需要根据你的环境和需求进行调整。如果你需要进一步的帮助,请提供更多关于你的具体需求和背景信息。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月27日
  • 修改了问题 6月26日
  • 修改了问题 6月26日
  • 创建了问题 6月26日