最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot和Vue.js項(xiàng)目中實(shí)現(xiàn)文件壓縮下載功能的具體方案

 更新時(shí)間:2025年09月29日 08:33:52   作者:IT界Tony哥  
在Spring Boot和Vue.js項(xiàng)目中實(shí)現(xiàn)文件壓縮下載功能,主要思路是后端負(fù)責(zé)將多個(gè)文件壓縮成ZIP包,前端負(fù)責(zé)觸發(fā)下載并處理文件流,以下是具體的實(shí)現(xiàn)方案,需要的朋友可以參考下

后端實(shí)現(xiàn)(Spring Boot)

后端需要完成的核心任務(wù)是接收文件ID列表,查詢(xún)對(duì)應(yīng)的文件路徑,將它們壓縮成ZIP文件,并通過(guò)HTTP響應(yīng)返回給前端。

1. 添加依賴(lài)

首先,在pom.xml中添加處理ZIP文件的依賴(lài),推薦使用功能強(qiáng)大的zip4j庫(kù)。

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.11.5</version>
</dependency>

2. 核心服務(wù)層代碼

創(chuàng)建一個(gè)Service方法,用于根據(jù)文件ID列表生成ZIP文件。此方法會(huì)查詢(xún)文件實(shí)體,構(gòu)建壓縮包內(nèi)的目錄結(jié)構(gòu),并將文件添加到ZIP中。

@Service
@Slf4j
public class FileDownloadService {

    @Autowired
    private SysDownloadCenterAttachmentMapper attachmentMapper;
    
    @Autowired
    private ScjtConfig scjtConfig; // 假設(shè)這個(gè)配置類(lèi)包含文件上傳的基礎(chǔ)路徑

    /**
     * 創(chuàng)建ZIP壓縮文件
     * @param ids 文件ID列表,用逗號(hào)分隔
     * @return 生成的ZIP文件在服務(wù)器上的絕對(duì)路徑
     */
    private String createZipFile(String ids) {
        // 將傳入的ID字符串轉(zhuǎn)換為整型數(shù)組
        Integer[] idArray = Convert.toIntArray(ids);
        List<String> allFilePaths = new ArrayList<>();

        // 1. 收集所有需要壓縮的文件路徑
        for (Integer id : idArray) {
            // 查詢(xún)?cè)揑D對(duì)應(yīng)的所有附件信息
            List<SysDownloadCenterAttachment> attachments = attachmentMapper.selectList(
                new LambdaQueryWrapper<SysDownloadCenterAttachment>()
                    .eq(SysDownloadCenterAttachment::getDownloadCenterId, id));
            
            if (!CollectionUtils.isEmpty(attachments)) {
                // 將附件信息轉(zhuǎn)換為完整的服務(wù)器文件路徑
                List<String> paths = attachments.stream().map(attachment -> {
                    String location = attachment.getLocation();
                    String fullPath = scjtConfig.getUploadPath() + location;
                    // 簡(jiǎn)單的路徑補(bǔ)全邏輯,請(qǐng)根據(jù)你的實(shí)際存儲(chǔ)結(jié)構(gòu)調(diào)整
                    if (!fullPath.startsWith("D:")) {
                        fullPath = "D:" + fullPath; // 示例路徑,請(qǐng)修改為你的實(shí)際存儲(chǔ)路徑
                    }
                    return fullPath;
                }).collect(Collectors.toList());
                allFilePaths.addAll(paths);
            }
        }

        // 2. 創(chuàng)建ZIP文件并添加內(nèi)容
        ZipFile zipFile = new ZipFile("d:/temp_download_filename.zip"); // 指定臨時(shí)ZIP文件路徑
        for (String filePath : allFilePaths) {
            File fileToAdd = new File(filePath);
            if (fileToAdd.exists()) {
                try {
                    // 設(shè)置ZIP文件參數(shù):壓縮方法、級(jí)別等
                    ZipParameters parameters = new ZipParameters();
                    parameters.setCompressionMethod(CompressionMethod.DEFLATE);
                    parameters.setCompressionLevel(CompressionLevel.NORMAL);
                    
                    // 可選:在ZIP包內(nèi)按原始目錄結(jié)構(gòu)組織文件,或自定義文件夾結(jié)構(gòu)
                    // 例如,設(shè)置文件在ZIP包內(nèi)的路徑和名稱(chēng)
                    parameters.setFileNameInZip(fileToAdd.getName()); 
                    
                    // 將文件添加到ZIP包
                    zipFile.addFile(fileToAdd, parameters);
                    log.info("文件已成功添加到ZIP: {}", filePath);
                } catch (ZipException e) {
                    log.error("添加文件到ZIP時(shí)出錯(cuò): {}", filePath, e);
                    throw new RuntimeException("壓縮文件失敗", e);
                }
            } else {
                log.warn("文件不存在,跳過(guò): {}", filePath);
            }
        }
        return zipFile.getFile().getAbsolutePath();
    }

    /**
     * 供Controller調(diào)用的下載入口方法
     */
    public ResponseEntity<Resource> downloadZip(String ids, HttpServletResponse response) throws FileNotFoundException {
        String zipFilePath = createZipFile(ids);
        File zipFile = new File(zipFilePath);
        
        // 將文件包裝成Spring的Resource對(duì)象(這里使用InputStreamResource)
        InputStreamResource resource = new InputStreamResource(new FileInputStream(zipFile));
        
        // 設(shè)置HTTP響應(yīng)頭,告訴瀏覽器這是一個(gè)需要下載的附件
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="download.zip"")
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .contentLength(zipFile.length())
                .body(resource);
    }
}

3. 控制器(Controller)

提供REST API接口給前端調(diào)用。

@RestController
@RequestMapping("/api/file")
public class FileDownloadController {

    @Autowired
    private FileDownloadService fileDownloadService;

    @PostMapping("/download-zip")
    public ResponseEntity<Resource> downloadZip(@RequestParam String ids, HttpServletResponse response) {
        try {
            return fileDownloadService.downloadZip(ids, response);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("ZIP文件未找到", e);
        }
    }
}

前端實(shí)現(xiàn)(Vue.js)

前端負(fù)責(zé)向后端接口發(fā)送請(qǐng)求,并將接收到的ZIP文件流保存為本地文件。

1. 安裝依賴(lài)(可選)

如果前端也需要處理壓縮(例如在瀏覽器端打包),可以安裝jszipfile-saver。但對(duì)于本文描述的后端壓縮方案,以下為最簡(jiǎn)實(shí)現(xiàn)。

npm install file-saver

2. 發(fā)起下載請(qǐng)求

創(chuàng)建一個(gè)方法來(lái)調(diào)用后端的下載接口。使用axios(或你項(xiàng)目使用的HTTP客戶(hù)端)時(shí),關(guān)鍵是指定responseType: 'blob',以便正確處理二進(jìn)制流響應(yīng)。

<template>
  <div>
    <button @click="handleBatchDownload">下載選中文件壓縮包</button>
  </div>
</template>

<script>
import axios from 'axios'; // 確保已安裝axios

export default {
  data() {
    return {
      selectedFileIds: [1, 2, 3] // 假設(shè)這是用戶(hù)選中的文件ID列表
    };
  },
  methods: {
    async handleBatchDownload() {
      try {
        // 將文件ID數(shù)組轉(zhuǎn)換為后端接口需要的格式,例如逗號(hào)分隔的字符串
        const idsParam = this.selectedFileIds.join(',');
        
        const response = await axios.post('/api/file/download-zip', 
          { ids: idsParam }, // 請(qǐng)求參數(shù)
          {
            responseType: 'blob' // 必須設(shè)置,告知axios期望接收二進(jìn)制數(shù)據(jù)
          }
        );

        // 處理下載的文件流
        if (response.data.size > 0) {
          // 創(chuàng)建一個(gè)指向Blob對(duì)象的URL
          const blobUrl = window.URL.createObjectURL(new Blob([response.data], { type: 'application/zip' }));
          
          // 創(chuàng)建一個(gè)隱藏的<a>標(biāo)簽并觸發(fā)點(diǎn)擊下載
          const link = document.createElement('a');
          link.style.display = 'none';
          link.href = blobUrl;
          link.download = 'files.zip'; // 設(shè)置下載的文件名
          document.body.appendChild(link);
          link.click();
          
          // 清理DOM和釋放Blob URL,避免內(nèi)存泄漏
          document.body.removeChild(link);
          window.URL.revokeObjectURL(blobUrl);
        } else {
          this.$message.error('沒(méi)有找到可下載的文件');
        }
      } catch (error) {
        console.error('下載失敗:', error);
        this.$message.error('文件下載失敗,請(qǐng)重試');
      }
    }
  }
};
</script>

性能與注意事項(xiàng)

  1. ??大文件與內(nèi)存管理??:對(duì)于超大文件或極多文件的壓縮,建議使用流式壓縮(如ZipOutputStream)而非一次性加載所有文件到內(nèi)存,避免內(nèi)存溢出(OOM)。后端示例中創(chuàng)建臨時(shí)文件的方式在文件很大時(shí)也需注意磁盤(pán)空間和IO性能。
  2. ??臨時(shí)文件清理??:后端生成的臨時(shí)ZIP文件應(yīng)在下載完成后或定期進(jìn)行清理,例如使用File.delete()或在項(xiàng)目啟動(dòng)時(shí)清理舊的臨時(shí)文件,以免占用過(guò)多磁盤(pán)空間。
  3. ??錯(cuò)誤處理??:增強(qiáng)代碼的健壯性,對(duì)文件不存在、網(wǎng)絡(luò)異常等情況進(jìn)行妥善處理,并給前端返回明確的錯(cuò)誤信息。
  4. ??安全考慮??:確保對(duì)文件ID進(jìn)行權(quán)限校驗(yàn),防止用戶(hù)通過(guò)篡改ID下載未經(jīng)授權(quán)的文件。

通過(guò)以上步驟,你就可以在Spring Boot和Vue.js項(xiàng)目中實(shí)現(xiàn)一個(gè)完整且健壯的文件壓縮下載功能了。

到此這篇關(guān)于SpringBoot和Vue.js項(xiàng)目中實(shí)現(xiàn)文件壓縮下載功能的具體方案的文章就介紹到這了,更多相關(guān)SpringBoot Vue.js文件壓縮下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java concurrency之AtomicReference原子類(lèi)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java concurrency之AtomicReference原子類(lèi)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    AtomicReference是作用是對(duì)"對(duì)象"進(jìn)行原子操作。這篇文章主要介紹了Java concurrency之AtomicReference原子類(lèi),需要的朋友可以參考下
    2017-06-06
  • Spring BeanName 的自動(dòng)生成原理示例詳解

    Spring BeanName 的自動(dòng)生成原理示例詳解

    這篇文章主要介紹了Spring BeanName 的自動(dòng)生成原理示例詳解,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Java ClassCastException異常解決方案

    Java ClassCastException異常解決方案

    這篇文章主要介紹了Java ClassCastException異常解決方案,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • java sql ResultSet 之getRow()用法說(shuō)明

    java sql ResultSet 之getRow()用法說(shuō)明

    這篇文章主要介紹了java sql ResultSet 之getRow()用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Spring Profile與PropertyPlaceholderConfigurer項(xiàng)目多環(huán)境配置切換

    Spring Profile與PropertyPlaceholderConfigurer項(xiàng)目多環(huán)境配置切換

    這篇文章主要介紹了Spring Profile與PropertyPlaceholderConfigurer項(xiàng)目多環(huán)境配置切換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • java.util.Date和java.time.LocalDate對(duì)比及分析

    java.util.Date和java.time.LocalDate對(duì)比及分析

    本文介紹了java.util.Date和java.time下的日期兩種日期類(lèi)型的區(qū)別和使用場(chǎng)景,前者表示一個(gè)瞬時(shí)時(shí)間點(diǎn),包含日期+時(shí)間,后者僅表示純?nèi)掌?后者時(shí)區(qū)無(wú)關(guān)聯(lián),而前者依賴(lài)操作系統(tǒng)時(shí)區(qū)顯示,兩者之間可以相互轉(zhuǎn)換,并且可以格式化輸出
    2026-05-05
  • 使用SpringBoot自定義starter的完整步驟

    使用SpringBoot自定義starter的完整步驟

    這篇文章主要給大家介紹了關(guān)于使用SpringBoot自定義starter的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Java8方法引用和構(gòu)造引用代碼實(shí)例

    Java8方法引用和構(gòu)造引用代碼實(shí)例

    這篇文章主要介紹了java8方法引用和構(gòu)造引用代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring?Validation中的用戶(hù)注冊(cè)、JWT令牌之用戶(hù)登入功能

    Spring?Validation中的用戶(hù)注冊(cè)、JWT令牌之用戶(hù)登入功能

    本文介紹了使用SpringValidation進(jìn)行用戶(hù)注冊(cè)驗(yàn)證和JWT進(jìn)行用戶(hù)登錄的方法,在用戶(hù)注冊(cè)時(shí),通過(guò)@Validated注解和@Pattern注解對(duì)用戶(hù)名和密碼進(jìn)行格式校驗(yàn),并使用Result對(duì)象返回驗(yàn)證結(jié)果,感興趣的朋友一起看看吧
    2024-11-11
  • java ZXing生成二維碼及條碼實(shí)例分享

    java ZXing生成二維碼及條碼實(shí)例分享

    本文分享了java ZXing生成二維碼及條碼的實(shí)例代碼,具有很好的參考價(jià)值,需要的朋友一起來(lái)看下吧
    2016-12-12

最新評(píng)論

黄梅县| 循化| 葫芦岛市| 方正县| 财经| 广宗县| 灵川县| 共和县| 长治县| 砀山县| 洛隆县| 陵水| 奇台县| 双江| 策勒县| 洛浦县| 广南县| 宜章县| 建宁县| 西畴县| 苍山县| 涿州市| 沧源| 团风县| 旌德县| 东宁县| 那曲县| 曲沃县| 固始县| 菏泽市| 偃师市| 新宁县| 绥芬河市| 政和县| 扎鲁特旗| 泾阳县| 泰州市| 山东| 全州县| 黔西| 临沂市|