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

SpringBoot返回文件使前端下載的幾種方式小結(jié)

 更新時(shí)間:2024年11月21日 09:37:46   作者:一朵梨花壓海棠go  
本文主要介紹了Spring Boot中幾種文件下載的方法,通過后端應(yīng)用下載文件并進(jìn)行業(yè)務(wù)處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

01 背景

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

  • 不通過后端應(yīng)用,直接使用nginx直接轉(zhuǎn)發(fā)文件地址下載(適用于一些公開的文件,因?yàn)檫@里不需要授權(quán))
  • 通過后端進(jìn)行下載,同時(shí)進(jìn)行一些業(yè)務(wù)處理

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

  • 讀取文件,得到文件的字節(jié)流
  • 將字節(jié)流寫入到響應(yīng)輸出流中

02 一次性讀取到內(nèi)存,通過響應(yīng)輸出流輸出到前端

    @GetMapping("/file/download")
    public void fileDownload(HttpServletResponse response, @RequestParam("filePath") String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new BusinessException("當(dāng)前下載的文件不存在,請檢查路徑是否正確");
        }

        // 將文件寫入輸入流
        try (InputStream is = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
            
            // 一次性讀取到內(nèi)存中
            byte[] buffer = new byte[is.available()];
            int read = is.read(buffer);

            // 清空 response
            response.reset();
            response.setCharacterEncoding("UTF-8");

            // Content-Disposition的作用:告知瀏覽器以何種方式顯示響應(yīng)返回的文件,用瀏覽器打開還是以附件的形式下載到本地保存
            // attachment表示以附件方式下載   inline表示在線打開   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默認(rèn)名稱,因?yàn)榫W(wǎng)絡(luò)傳輸只支持URL編碼的相關(guān)支付,因此需要將文件名URL編碼后進(jìn)行傳輸,前端收到后需要反編碼才能獲取到真正的名稱
            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);
        }

    }

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

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

    @GetMapping("/file/download")
    public void fileDownload(HttpServletResponse response, @RequestParam("filePath") String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new BusinessException("當(dāng)前下載的文件不存在,請檢查路徑是否正確");
        }

        // 清空 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);
        }

    }

04 從網(wǎng)絡(luò)上獲取文件并返回給前端

    @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);
        }
        
    }

05 從網(wǎng)絡(luò)上獲取文本并下載到本地

    @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);
        }

    }

06 總結(jié)

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

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

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

相關(guān)文章

  • Java使用Zxing二維碼生成的簡單示例

    Java使用Zxing二維碼生成的簡單示例

    ZXing是一個(gè)開源的,用Java實(shí)現(xiàn)的多種格式的1D/2D條碼圖像處理庫,下面這篇文章主要給大家介紹了關(guān)于Java使用Zxing二維碼生成的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 如何使用mybatis-plus實(shí)現(xiàn)分頁查詢功能

    如何使用mybatis-plus實(shí)現(xiàn)分頁查詢功能

    最近在研究mybatis,然后就去找簡化mybatis開發(fā)的工具,發(fā)現(xiàn)就有通用Mapper和mybatis-plus兩個(gè)比較好的可是使用,可是經(jīng)過對比發(fā)現(xiàn)還是mybatis-plus比較好,下面這篇文章主要給大家介紹了關(guān)于如何使用mybatis-plus實(shí)現(xiàn)分頁查詢功能的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 使用SpringBoot動(dòng)態(tài)切換數(shù)據(jù)源的實(shí)現(xiàn)方式

    使用SpringBoot動(dòng)態(tài)切換數(shù)據(jù)源的實(shí)現(xiàn)方式

    在我們企業(yè)項(xiàng)目開發(fā)的過程中,有的時(shí)候,一個(gè)項(xiàng)目需要在運(yùn)行時(shí),根據(jù)某種條件選擇使用哪個(gè)數(shù)據(jù)源,那么此時(shí)該怎么進(jìn)行動(dòng)態(tài)切換呢,本文給大家例舉一種常見的實(shí)現(xiàn)方式,文中有詳細(xì)的實(shí)現(xiàn)步驟,需要的朋友可以參考下
    2023-12-12
  • Spring Boot統(tǒng)一異常攔截實(shí)踐指南(最新推薦)

    Spring Boot統(tǒng)一異常攔截實(shí)踐指南(最新推薦)

    本文介紹了Spring Boot中統(tǒng)一異常處理的重要性及實(shí)現(xiàn)方案,包括使用`@ControllerAdvice`和`@ExceptionHandler`注解,實(shí)現(xiàn)全局異常處理和統(tǒng)一響應(yīng)格式,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-02-02
  • java?實(shí)現(xiàn)獲取指定位置后的第一個(gè)數(shù)字

    java?實(shí)現(xiàn)獲取指定位置后的第一個(gè)數(shù)字

    這篇文章主要介紹了java?實(shí)現(xiàn)獲取指定位置后的第一個(gè)數(shù)字,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 基于SSM實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    基于SSM實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了基于SSM實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Mybatis一對多查詢的兩種姿勢(值得收藏)

    Mybatis一對多查詢的兩種姿勢(值得收藏)

    這篇文章主要給大家介紹了關(guān)于Mybatis一對多查詢的兩種姿勢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 手寫java性能測試框架第二版

    手寫java性能測試框架第二版

    這篇文章主要為大家介紹了手寫java性能測試框架第二版實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Java封裝實(shí)現(xiàn)自適應(yīng)的單位轉(zhuǎn)換工具類

    Java封裝實(shí)現(xiàn)自適應(yīng)的單位轉(zhuǎn)換工具類

    這篇文章主要為大家詳細(xì)介紹了如何使用Java封裝實(shí)現(xiàn)一個(gè)自適應(yīng)的單位轉(zhuǎn)換工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • 面試官:Java中new Object()到底占用幾個(gè)字節(jié)

    面試官:Java中new Object()到底占用幾個(gè)字節(jié)

    這篇文章主要介紹了面試官:Java中new Object()到底占用幾個(gè)字節(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02

最新評論

徐水县| 周口市| 贺州市| 西吉县| 扶余县| 黔南| 从江县| 吐鲁番市| 恩平市| 东乌| 保山市| 乡城县| 固原市| 邢台县| 平山县| 林周县| 扎囊县| 兰溪市| 白沙| 巩义市| 广平县| 高密市| 合阳县| 高密市| 八宿县| 永康市| 鲁山县| 崇州市| 体育| 尼勒克县| 宝应县| 青冈县| 谷城县| 济宁市| 塔河县| 太仆寺旗| 广南县| 白银市| 松阳县| 神农架林区| 霍州市|