1. 程式人生 > >SpringBoot搭建的Web服務文字檔案和gzip下載

SpringBoot搭建的Web服務文字檔案和gzip下載

簡介

本文主要介紹基於SpringBoot搭建的Web服務,對於文字檔案(txt)和文字檔案壓縮包(gzip)的下載操作。

下載操作

由於我們主要介紹文字檔案的下載操作,將重點集中在Controller中方法的實現,對於SpringBoot搭建Web服務就不再介紹。

基於SpringBoot搭建Web服務可參考另外一篇博文:基於SpringBoot搭建Web服務

下載操作包含3個型別

  • 將字串寫入到檔案中提供下載
  • 下載本地文字檔案
  • 本地文字檔案轉成GZIP壓縮包下載

Controller

新建DownloadController.class

新增@RestController註解,程式碼如下:

package hello.controller;

import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.
web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; /** * Created on 2018/12/20. * * @author Marvin Yang */ @RestController public class DownloadController
{ }

將字串寫入到檔案中下載

DownloadController.class 中新增方法downloadFile實現將字串寫入到檔案中並提供下載操作。有兩點需要注意,(1) 函式無返回值;(2) 選擇HttpServletResponse作為返回。

	/**
     * txt檔案下載介面
     *  1. 將字串寫入到檔案中提供下載
     *
     * @param response a HttpServletResponse
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public void downloadFile(HttpServletResponse response) {
        // set header
        response.setHeader("Content-Disposition", "attachment; filename=demo.txt");
        String demo = "Here is a demo of download file.";
        try {
            response.getOutputStream().write(demo.getBytes());
            response.flushBuffer();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

在瀏覽器請求,測試樣例如下:

# 8080是web埠 
http://localhost:8080/download?

下載本地文字檔案

DownloadController.class 中新增方法downloadLocalFile實現本地文字檔案的下載操作。有3點需要注意,(1) URL呼叫方式為/download/{fileName} ; (2) InputStream必須close(),否則一旦介面被呼叫,該檔案在本地則不允許刪除,除非關閉web服務; (3) 注意本地檔案的路徑,保證可以獲取到。

	/**
     * 下載本地文字檔案
     *  1. FileInputStream必須close, 否則會被佔用, 導致如果web服務不關閉檔案無法被本地刪除
     *
     * @param fileName 本地文字檔名稱
     * @param response a HttpServletResponse
     */
    @RequestMapping(value = "/download/{fileName}", method = RequestMethod.GET)
    public void downloadLocalFile(@PathVariable("fileName") String fileName, HttpServletResponse response) {
        // set header
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        FileInputStream inputStream = null;
        try {
            File file = new File(fileName);
            if (!file.exists()) {
                String errorMsg = "Can not find such file: " + fileName;
                response.getOutputStream().write(errorMsg.getBytes());
            } else {
                inputStream = new FileInputStream(fileName);
                IOUtils.copy(inputStream, response.getOutputStream());
            }
            response.flushBuffer();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ignore) {}
            }
        }
    }

在瀏覽器請求,測試樣例如下:

# 8080是web埠
# demo_local是本地檔名稱(注意檔案路徑)
http://localhost:8080/download/demo_local?

本地文字檔案轉成GZIP壓縮包下載

DownloadController.class 中新增方法downloadLocalFile實現本地文字檔案讀取並轉換為gzip下載。有2點需要注意,(1) 設定content-type; (2) response.getOutputStream()需要使用GZIPOutputStream

	 /**
     * 本地文字檔案轉成GZIP壓縮包下載
     *  1. FileInputStream必須close, 否則會被佔用, 導致如果web服務不關閉檔案無法被本地刪除
     *
     * @param fileName 本地文字檔名稱
     * @param response HttpServletResponse
     */
    @RequestMapping(value = "/download/zip/{fileName}", method = RequestMethod.GET)
    public void downloadLocalGZip(@PathVariable("fileName") String fileName, HttpServletResponse response) {
        // set header
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".gz");
        response.setContentType("application/zip");
        FileInputStream inputStream = null;
        try (GZIPOutputStream outputStream = new GZIPOutputStream(response.getOutputStream())){
            File file = new File(fileName);
            if (!file.exists()) {
                String errorMsg = "can not find such file: " + fileName;
                response.getOutputStream().write(errorMsg.getBytes());
            } else {
                inputStream = new FileInputStream(fileName);
                IOUtils.copy(inputStream, outputStream);
            }
            response.flushBuffer();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ignore) {}
            }
        }
    }

在瀏覽器請求,測試樣例如下:

# 8080是web埠
# demo_local是本地檔名稱(注意檔案路徑)
http://localhost:8080/download/zip/demo_local?

總結

我們介紹了RestControllerservice服務提供文字檔案和gzip壓縮包的下載操作。

如果是讀取其他型別的檔案,則嘗試修改InputStream的型別完成檔案讀取;如果是zip型別的檔案下載,則可以使用java.util.zip.ZipOutputStream,注意zip的操作不同於gzip操作。

參考文獻

https://stackoverflow.com/questions/27952949/spring-rest-create-zip-file-and-send-it-to-the-client/40498539#40498539