日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

目前,網(wǎng)上一搜SpringBoot環(huán)境下載文件。有多種實(shí)現(xiàn)方式,大概率出來(lái)的會(huì)是基礎(chǔ)版的,基礎(chǔ)版的有幾個(gè)坑,我這里分別將基礎(chǔ)版以及基礎(chǔ)版會(huì)出現(xiàn)的問(wèn)題,從而引申各種解決方法。

基礎(chǔ)版

話不多說(shuō),直接上源碼:

@RestController
public class TestDownload {
    @Value("${gen.base.path}")
    private String baseFilePath;
    @ApiOperation(value = "SpringBoot實(shí)現(xiàn)文件下載", notes = "基礎(chǔ)版")
    @RequestMApping(value = "/baseDownload", method = RequestMethod.GET)
    @ResponseBody
   public ResponseEntity<InputStreamResource> baseDownload(@RequestParam("fileId") String fileId) throws Exception {
        FileSystemResource file = new FileSystemResource(baseFilePath+fileId+".pdf");
        if (!file.exists()) {
        throw new HaBizException(1,"請(qǐng)您輸入正確的文件ID");
    }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", String.format("attachment; filename=%s", file.getFilename()));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.contentLength())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new InputStreamResource(file.getInputStream()));
    }

}

這個(gè)基礎(chǔ)版是有兩個(gè)問(wèn)題:

1、不能手動(dòng)(主動(dòng))關(guān)閉文件流
2、下載文件較大時(shí),jvm會(huì)內(nèi)存溢出。

2. 進(jìn)階版

主動(dòng)關(guān)閉文件流。

@ApiOperation(value = "SpringBoot實(shí)現(xiàn)文件下載", notes = "進(jìn)階版")
@RequestMapping(value = "/advancedDownload", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<StreamingResponseBody> advancedDownload(@RequestParam("fileId") String fileId) throws Exception {
    FileSystemResource file = new FileSystemResource(baseFilePath+fileId);
    if (!file.exists()) {
        throw  new HaBizException(1,"請(qǐng)您輸入正確的文件ID");
    }
    InputStream inputStream = file.getInputStream();
    StreamingResponseBody responseBody = outputStream -> {
        int numberOfBytesToWrite;
        byte[] data = new byte[1024];
        while ((numberOfBytesToWrite = inputStream.read(data, 0, data.length)) != -1) {
            outputStream.write(data, 0, numberOfBytesToWrite);
        }
        inputStream.close();
    };
    HttpHeaders headers = new HttpHeaders();
    headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
    headers.add("Content-Disposition", String.format("attachment; filename=%s", file.getFilename()));
    headers.add("Pragma", "no-cache");
    headers.add("Expires", "0");
    return ResponseEntity.ok()
            .headers(headers)
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(responseBody);
}

這個(gè)版本普遍適用,但是仍然不能解決下載文件較大導(dǎo)致內(nèi)存溢出的問(wèn)題,所以這里就來(lái)個(gè)功能更全一點(diǎn)的,使用緩存流,邊讀邊寫

3. 高級(jí)版

使用緩存流,邊讀邊寫

@ApiOperation(value = "SpringBoot實(shí)現(xiàn)文件下載", notes = "使用緩存流,邊讀邊寫")
@RequestMapping(value = "/cacheDownload", method = RequestMethod.GET)
@ResponseBody
public void cacheDownload(@RequestParam("fileId") String fileId, HttpServletResponse response) throws Exception {
    FileSystemResource file = new FileSystemResource(baseFilePath+fileId);
    if (!file.exists()) {
        throw  new HaBizException(1,"請(qǐng)您輸入正確的文件ID");
    }
    String filename = file.getFilename();
    InputStream inputStream = null;
    BufferedInputStream bufferedInputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
    try {
        inputStream = file.getInputStream();
        bufferedInputStream = new BufferedInputStream(inputStream);
        bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
        FileCopyUtils.copy(bufferedInputStream, bufferedOutputStream);
        }catch(Exception e){
            throw  new HaBizException(1,"下載文件異常"+e);
        }finally {
            if(null!=inputStream){
                inputStream.close();
            }
            if(null!=bufferedInputStream){
                bufferedInputStream.close();
            }
            if(null!=bufferedOutputStream){
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
            }
    }
}

當(dāng)然,如果不想使用JAVA自帶的BufferedInputStream當(dāng)緩沖區(qū)的話,也可以自己寫,例子如下

@RequestMapping("/baseCacheDownload")
public void baseCacheDownload(@RequestParam("fileId") String fileId, HttpServletResponse response) throws Exception {
    FileSystemResource file = new FileSystemResource(baseFilePath+fileId);
    if (!file.exists()) {
        throw  new HaBizException(1,"請(qǐng)您輸入正確的文件ID");
    }
    InputStream inputStream = file.getInputStream();// 文件的存放路徑
    response.reset();
    response.setContentType("application/octet-stream");
    String filename = file.getFilename();
    response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));//①tips
    ServletOutputStream outputStream = response.getOutputStream();
    byte[] b = new byte[1024];
    int len;
    //緩沖區(qū)(自己可以設(shè)置大小):從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)字節(jié)數(shù)組中,讀到末尾返回-1
    while ((len = inputStream.read(b)) > 0) {
        outputStream.write(b, 0, len);
    }
    inputStream.close();
}

這里有一個(gè)技巧,

①tips處的代碼,Content-disposition 為屬性名。
attachment 表示以附件方式下載。
如果要在頁(yè)面中打開(kāi),則改為 inline。

filename 如果為中文,則會(huì)出現(xiàn)亂碼。
解決辦法有兩種:
1、 使用 fileName = new String(fileName.getBytes(), “ISO8859-1”) 語(yǔ)句
2、使用 fileName = HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8) 語(yǔ)句

分享到:
標(biāo)簽:SpringBoot
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定