染指余忆 2024-02-03 11:14 采纳率: 96.3%
浏览 1
已结题

使用ResponseEntity免压缩多文件下载

如何使用ResponseEntity免压缩多文件下载,前端使用xml.setRequestHeader(),后端是mvc

  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-03 11:15
    关注

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

    在Spring MVC中,使用ResponseEntity来实现免压缩多文件下载通常涉及将多个文件合并成一个字节数组或流,并以某种格式(例如ZIP)打包发送给前端,而不是直接一次性下载多个独立文件。由于HTTP协议本身不直接支持一次请求下载多个独立文件,所以后端需要进行一定的处理。

    以下是一个示例,演示如何将多个文件内容合并到一个ByteArrayResource中并返回给前端下载:

    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.core.io.ByteArrayResource;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.List;
    import java.util.stream.Collectors;
    
    @Controller
    @RequestMapping("/download")
    public class MultiFileDownloadController {
    
        // 假设你有一个方法用于获取多个文件的字节数组列表
        private List<byte[]> getFilesBytesList(List<Path> filePaths) throws IOException {
            return filePaths.stream()
                    .map(path -> {
                        try {
                            return Files.readAllBytes(path);
                        } catch (IOException e) {
                            throw new RuntimeException("Failed to read file", e);
                        }
                    })
                    .collect(Collectors.toList());
        }
    
        @GetMapping("/multiple")
        public ResponseEntity<ByteArrayResource> downloadMultipleFiles(List<Path> filePaths) throws IOException {
            // 获取所有文件的字节数据
            List<byte[]> filesData = getFilesBytesList(filePaths);
    
            // 将多个文件内容合并为一个字节数组,这里仅作演示,实际应用可能需要打包为zip等格式
            byte[] combinedData = concatenateFiles(filesData); 
    
            // 设置响应头,这里是原始数据,无压缩
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            String filename = "combined_files.bin";  // 自定义下载的文件名
            headers.setContentDispositionFormData(filename, null);
    
            ByteArrayResource resource = new ByteArrayResource(combinedData);
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(combinedData.length)
                    .body(resource);
        }
    
        // 合并多个文件字节数组的方法,简单地串联起来,实际应用中可能需要按特定格式如ZIP打包
        private byte[] concatenateFiles(List<byte[]> filesData) {
            int totalSize = filesData.stream().mapToInt(byte[].::length).sum();
            byte[] result = new byte[totalSize];
            int offset = 0;
            for (byte[] file : filesData) {
                System.arraycopy(file, 0, result, offset, file.length);
                offset += file.length;
            }
            return result;
        }
    
        // 前端设置xhr请求时可以这样:
        // 注意:XMLHttpRequest默认不会触发下载,若要自动下载,需配合a标签模拟点击或创建Blob对象
        var xhr = new XMLHttpRequest();
        xhr.open('GET', '/download/multiple', true);
        xhr.setRequestHeader('Content-Type', 'application/octet-stream');
        xhr.responseType = 'blob';
        xhr.onload = function() {
            if (this.status === 200) {
                var blob = this.response;
                var url = window.URL.createObjectURL(blob);
                var a = document.createElement('a');
                a.href = url;
                a.download = 'combined_files.bin';  // 文件名应与后端设置的一致
                document.body.appendChild(a);
                a.click();
                setTimeout(function() {
                    window.URL.revokeObjectURL(url);
                    document.body.removeChild(a);
                }, 0);
            }
        };
        xhr.send();
    }
    

    请注意,上述代码为了简化演示,只是简单地将多个文件的内容拼接在一起,而实际场景中,如果需要用户下载的是多个独立文件,建议将其打包成ZIP或其他可解压格式,然后发送这个压缩包供用户下载。同时,前端部分展示了如何通过XMLHttpRequest设置请求头并处理响应体以实现下载功能。

    此外,请确保你的服务端已正确配置了跨域策略(CORS),以便前端可以成功发起请求。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 2月19日
  • 已采纳回答 2月11日
  • 创建了问题 2月3日

悬赏问题

  • ¥15 app:debugCompileClasspath'.
  • ¥20 公众号如何实现点击超链接后自动发送文字
  • ¥15 用php隐藏类名和增加类名
  • ¥15 算法设计与分析课程的提问
  • ¥15 用MATLAB汇总拟合图
  • ¥15 智能除草机器人方案设计
  • ¥15 对接wps协作接口实现消息发送
  • ¥15 SQLite 出现“Database is locked” 如何解决?
  • ¥15 已经加了学校的隶属邮箱了,为什么还是进不去github education?😭
  • ¥15 求会做聚类,TCN的朋友有偿线上指导。以下是目前遇到的问题