SpringCloud 通過feign檔案傳輸並打zip包下載

樂百壽發表於2020-11-07

一:檔案打zip包並下載;

準備兩個專案88008899
8899:負責提供檔案的下載服務;
8800:負責去8899資源管理工程下載檔案,並打zip包下載;

1):檔案資源提供方8899程式碼

@RestController
public class DownloadFileController {

    private static Logger logger = Logger.getLogger(DownloadFileController.class);

    @PostMapping(value = "/download/file")
    public void downloadFile(HttpServletResponse response,@RequestParam String filePath){

        logger.info("檔案路徑:"+filePath);
		//這裡模擬去資源伺服器下載的過程
        File file = new File(filePath);
		//file物件轉byte[],實際可能是將流物件轉byte[],所以這個方法的程式碼根據實際情況而定;
        byte[] filebyte = this.Filebyte(file);

        try {
            ServletOutputStream outputStream = response.getOutputStream();
            //這裡需要的就是個byte數字,實際去資源伺服器下載可能會得到流物件如:inputStream,實際只需將inputSteam轉為byte[]即可;
            outputStream.write(filebyte);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * File 轉 byte陣列
     * @param tradeFile
     * @return
     */
    public  byte[] Filebyte(File tradeFile){
        byte[] buffer = null;
        try
        {
            FileInputStream fis = new FileInputStream(tradeFile);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer;
    }
}

2):8800檔案加工打zip包的服務;

1,打zip包需要引入相關依賴;

<!--檔案下載打包-->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-compress</artifactId>
	<version>1.18</version>
</dependency>

2,呼叫8899下載檔案的介面;

@FeignClient(value = "ZT-FRANK-ENCRYPTION-PROVIDER-SERVICE-8899")
public interface IDownloadClientService {

    @PostMapping(value = "/download/file")
    Response downloadfile(@RequestParam String filePath);
}

3):打zip包以及檔案下載完整程式碼;

@RestController
public class DownloadFileController {

    private static Logger logger = Logger.getLogger(DownloadFileController.class);

    @Autowired
    private IDownloadClientService downloadClientService;

    @RequestMapping(value = "/download/zip")
    public void downloadFile(HttpServletResponse response){

        List<String> list = new ArrayList<>();
        list.add("D:/Project/TestData/aa.txt");
        list.add("D:/Project/TestData/bb.txt");
        list.add("D:/Project/TestData/cc.txt");
        /**
         * 邊下載邊打包zip
         */
        String downloadName = "Test附件.zip";
        try {
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(downloadName, "UTF-8"));
        } catch (Exception e) {
            logger.info("下載檔名編碼時出現錯誤.", e);
        }

        OutputStream outputStream = null;
        ZipOutputStream zos = null;
        try {
            outputStream = response.getOutputStream();
            zos = new ZipOutputStream(outputStream);
            // ***將檔案流寫入zip中***
            this.downloadTolocal(zos,list);
        } catch (IOException e) {
            logger.error("downloadAllFile-xxx下載全部附件失敗,錯誤資訊=[{}]",e);
        }finally {
            if(zos != null) {
                try {
                    zos.close();
                } catch (Exception e2) {
                    logger.info("關閉輸入流時出現錯誤",e2);
                }
            }
            if(outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e2) {
                    logger.info("關閉輸入流時出現錯誤",e2);
                }
            }

        }
    }

    private void downloadTolocal(ZipOutputStream zos,List<String> list ) throws IOException {

        for (int i =0;i<list.size();i++) {
            InputStream is = null;
            BufferedInputStream in = null;
            byte[] buffer = new byte[1024];
            int len;
            //建立zip實體(一個檔案對應一個ZipEntry)
            ZipEntry entry = new ZipEntry(i+"AA.txt");
            try {
                //***獲取需要下載的檔案流***
                is = this.download(list.get(i));
                in = new BufferedInputStream(is);
                zos.putNextEntry(entry);
                //檔案流迴圈寫入ZipOutputStream
                while ((len = in.read(buffer)) != -1 ) {
                    zos.write(buffer, 0, len);
                }
            } catch (Exception e) {
                logger.info("xxx--下載全部附件--壓縮檔案出錯",e);
            }finally {
                if(entry != null) {
                    try {
                        zos.closeEntry();
                    } catch (Exception e2) {
                        logger.info("xxx下載全部附件--zip實體關閉失敗",e2);
                    }
                }
                if(in != null) {
                    try {
                        in.close();
                    } catch (Exception e2) {
                        logger.info("xxx下載全部附件--檔案輸入流關閉失敗",e2);
                    }
                }
                if(is != null) {
                    try {
                        is.close();
                    }catch (Exception e) {
                        logger.info("xxx下載全部附件--輸入緩衝流關閉失敗",e);
                    }
                }
            }

        }
    }

    /**
     *8899服務通過feign下載檔案;
     * @param filePath
     * @return
     */
    public InputStream download(String filePath){
        //去8899服務通過feign下載檔案;
        Response resp = downloadClientService.downloadfile(filePath);
        Response.Body body = resp.body();
        try {
            //得到檔案流物件
            InputStream inputStream = body.asInputStream();
            return inputStream;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

3):測試瀏覽器訪問8800的下載介面 http://localhost:8800/download/zip

在這裡插入圖片描述
開啟下載的檔案,檔名就是程式碼裡面自定義的檔名;
在這裡插入圖片描述

相關文章