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

SpringBoot返回文件讓前端下載的幾種方式

 更新時間:2025年12月01日 11:47:32   作者:N***p365  
文章介紹了開發(fā)中文件下載的兩種常見解決方案,并詳細描述了通過后端進行下載的原理和步驟,包括一次性讀取到內存和分塊寫入響應輸出流兩種方法,此外,還提供了從網絡上獲取文件和文本并下載的示例,并總結了InputStream和OutputStream的區(qū)別,感興趣的朋友跟隨小編一起看看吧

01 背景

在后端開發(fā)中,通常會有文件下載的需求,常用的解決方案有兩種:

  1. 不通過后端應用,直接使用nginx直接轉發(fā)文件地址下載(適用于一些公開的文件,因為這里不需要授權)
  2. 通過后端進行下載,同時進行一些業(yè)務處理

本篇主要以方法2進行介紹,方法2的原理步驟如下:

  1. 讀取文件,得到文件的字節(jié)流
  2. 將字節(jié)流寫入到響應輸出流中

02 一次性讀取到內存,通過響應輸出流輸出到前端

    @GetMapping("/file/download")
    public void fileDownload(HttpServletResponse response, @RequestParam("filePath") String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new BusinessException("當前下載的文件不存在,請檢查路徑是否正確");
        }
        // 將文件寫入輸入流
        try (InputStream is = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
            // 一次性讀取到內存中
            byte[] buffer = new byte[is.available()];
            int read = is.read(buffer);
            // 清空 response
            response.reset();
            response.setCharacterEncoding("UTF-8");
            // Content-Disposition的作用:告知瀏覽器以何種方式顯示響應返回的文件,用瀏覽器打開還是以附件的形式下載到本地保存
            // attachment表示以附件方式下載   inline表示在線打開   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默認名稱,因為網絡傳輸只支持URL編碼的相關支付,因此需要將文件名URL編碼后進行傳輸,前端收到后需要反編碼才能獲取到真正的名稱
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            // 告知瀏覽器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

適用于小文件,如果文件過大,一次性讀取到內存中可能會出現(xiàn)oom的問題

02 將文件流通過循環(huán)寫入到響應輸出流中(推薦)

    @GetMapping("/file/download")
    public void fileDownload(HttpServletResponse response, @RequestParam("filePath") String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new BusinessException("當前下載的文件不存在,請檢查路徑是否正確");
        }
        // 清空 response
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
        response.setContentType("application/octet-stream");
        // 將文件讀到輸入流中
        try (InputStream is = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            byte[] buffer = new byte[1024];
            int len;
            //從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲在緩沖區(qū)字節(jié)數(shù)組中,讀到末尾返回-1
            while((len = is.read(buffer)) > 0){
                outputStream.write(buffer, 0, len);
            }
            outputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

03 從網絡上獲取文件并返回給前端

    @GetMapping("/net/download")
    public void netDownload(HttpServletResponse response, @RequestParam("fileAddress") String fileAddress, @RequestParam("filename") String filename) {
        try {
            URL url = new URL(fileAddress);
            URLConnection conn = url.openConnection();
            InputStream inputStream = conn.getInputStream();
            response.reset();
            response.setContentType(conn.getContentType());
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            byte[] buffer = new byte[1024];
            int len;
            OutputStream outputStream = response.getOutputStream();
            while ((len = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

04 從網絡上獲取文本并下載到本地

    @GetMapping("/netDownloadLocal")
    public void downloadNet(@RequestParam("netAddress") String netAddress, @RequestParam("filepath") String filepath) {
        try {
            URL url = new URL(netAddress);
            URLConnection conn = url.openConnection();
            InputStream inputStream = conn.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream(filepath);
            int byteread;
            byte[] buffer = new byte[1024];
            while ((byteread = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, byteread);
            }
            fileOutputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

05 總結

一定要搞清楚InputStreamOutputStream的區(qū)別,如果搞不清楚的,可以和字符流進行映射,InputStream -> Reader,OutPutStream -> Writer,換成這樣你就知道讀取內容需要使用Reader,寫入需要使用Writer了。

返回給前端的是輸出流,不需要你顯示的去返回(return response;),這樣會報錯

到此這篇關于SpringBoot返回文件讓前端下載的幾種方式的文章就介紹到這了,更多相關springboot文件下載內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java 二維數(shù)組矩陣乘法的實現(xiàn)方法

    java 二維數(shù)組矩陣乘法的實現(xiàn)方法

    java 二維數(shù)組矩陣乘法的實現(xiàn)方法,需要的朋友可以參考一下
    2013-03-03
  • Java編程讀寫鎖詳解

    Java編程讀寫鎖詳解

    本篇文章給大家詳細分享了Java編程讀寫鎖的相關原理以及知識點內容,有興趣的朋友們可以參考下。
    2018-08-08
  • Java Collection 體系與使用場景多角度分析

    Java Collection 體系與使用場景多角度分析

    本文從抽象層級、接口設計和實際使用場景三個角度,系統(tǒng)介紹了Java Collection框架,文章詳細說明了Collection的基本概念、Collection在體系中的位置、為什么要有Collection接口以及在不同場景下的使用建議,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Java快速實現(xiàn)短信登錄的詳細流程

    Java快速實現(xiàn)短信登錄的詳細流程

    短信登錄是基于短信驗證碼的身份驗證方式,在許多網站和應用中被廣泛使用,通常被認為比傳統(tǒng)的用戶名和密碼更安全,因為驗證碼是一次性使用的,且只有用戶能夠接收到短信,本文給大家介紹了Java快速實現(xiàn)短信登錄的詳細流程,需要的朋友可以參考下
    2025-08-08
  • SpringBoot 集成 Statemachine的實戰(zhàn)指南

    SpringBoot 集成 Statemachine的實戰(zhàn)指南

    本文介紹了Spring State Machine框架的基本概念、核心特性、注解驅動開發(fā)方式以及如何在Spring Boot項目中集成狀態(tài)機,通過狀態(tài)機,可以有效地管理復雜的狀態(tài)流轉邏輯,文章還討論了狀態(tài)機的持久化問題,并提供了一個自定義持久化實現(xiàn)的示例,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • MyBatis實現(xiàn)注冊及獲取Mapper

    MyBatis實現(xiàn)注冊及獲取Mapper

    本文主要介紹了MyBatis實現(xiàn)注冊及獲取Mapper,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-03-03
  • 關于Java中的mysql時區(qū)問題詳解

    關于Java中的mysql時區(qū)問題詳解

    這篇文章主要給大家介紹了關于Java中mysql時區(qū)問題的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-05-05
  • Java基于JDK 1.8的LinkedList源碼詳析

    Java基于JDK 1.8的LinkedList源碼詳析

    這篇文章主要給大家介紹了關于Java基于JDK 1.8的LinkedList源碼的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • Mybatis使用IN語句查詢的實現(xiàn)

    Mybatis使用IN語句查詢的實現(xiàn)

    這篇文章主要介紹了Mybatis使用IN語句查詢的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Java實現(xiàn)高效PDF文件傳輸技巧

    Java實現(xiàn)高效PDF文件傳輸技巧

    你是否曾為PDF文件傳輸?shù)牡托识鄲溃楷F(xiàn)在,有了這份Java實現(xiàn)高效PDF文件傳輸技巧指南,你將能夠輕松解決這個問題,我們將分享一些實用的技巧和最佳實踐,幫助你優(yōu)化文件傳輸過程,不要錯過這個提高工作效率的機會,快來閱讀這份指南吧!
    2024-03-03

最新評論

阜宁县| 义乌市| 柳江县| 颍上县| 石城县| 尚志市| 通州市| 通州区| 合阳县| 论坛| 扎鲁特旗| 菏泽市| 中牟县| 乳源| 鄯善县| 高碑店市| 郸城县| 凯里市| 岑巩县| 库尔勒市| 阿合奇县| 苍溪县| 长子县| 缙云县| 绥宁县| 平谷区| 松阳县| 图们市| 长沙市| 遵化市| 秦皇岛市| 泊头市| 阜宁县| 光泽县| 新乡市| 阿坝县| 内乡县| 济阳县| 磴口县| 新源县| 博湖县|