0
点赞
收藏
分享

微信扫一扫

java实现下载的问题

Villagers 2022-02-17 阅读 71
  1. 这种会出现pdf,txt,jpg…这些常见格式的文件在web浏览器以预览的形式出现,而不是需要的下载
function downloadFile(url, fileName, parameter) {
  return downFile(url, parameter).then((data) => {
    if (!data || data.size === 0) {
      Vue.prototype['$message'].warning('文件下载失败')
      return
    }
    if (typeof window.navigator.msSaveBlob !== 'undefined') {
      window.navigator.msSaveBlob(new Blob([data]), fileName)
    } else {
      let url = window.URL.createObjectURL(new Blob([data]))
      let link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', fileName)
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link) //下载完成移除元素
      window.URL.revokeObjectURL(url) //释放掉blob对象
    }
  })
}
        File file = new File(path);
        if(!file.exists()){
            response.setStatus(404);
            throw new RuntimeException("文件不存在..");
        }
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            response.reset();
            
            outputStream = new BufferedOutputStream(response.getOutputStream());
            inputStream = new BufferedInputStream(new FileInputStream(file));
            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                outputStream.write(buf, 0, len);
                outputStream.flush();
            }
            response.setContentLength((int )file.length());
            response.setContentType("application/force-download");
            response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
        } catch (IOException e) {
            log.info("读取文件失败" + e.getMessage());
            response.setStatus(404);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

上述代码有两个问题:

  1. java中发现response设置contentType无效
  2. js中先完整的获取二进制流,然后封装成blob文件对象,也就是先执行了文件下载请求,但是在客户端看不到过程,遇到较大文件时,用户无法感知,体验很差

解决办法:

  • java中
    改变下设置contentType和获取输出流的顺序,如下
	response.reset();
    response.setContentLength((int )file.length());
    response.setContentType("application/force-download");
    response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
    outputStream = new BufferedOutputStream(response.getOutputStream());
    inputStream = new BufferedInputStream(new FileInputStream(file));
            
  • js中
    不直接获取完整的二进制流,之前文件的相关设置是在前端做的,现在都放在后端
function downloadFile(url,filename){
	let link = document.createElement('a')
	link.style.display = 'none'
	link.href = url
	document.body.appendChild(link)
	link.click()
	document.body.removeChild(link) //下载完成移除元素
	window.URL.revokeObjectURL(url) //释放掉blob对象
}
举报

相关推荐

0 条评论