Springboot 文件下载代码

本文介绍了一种使用JSP实现文件下载的方法,并详细解释了如何从前端处理由后台返回的文件流来实现文件下载。同时,针对具体的技术问题提供了有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一。JSP 式样的

public HttpServletResponse download(String path, HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return response;
    }

二。前后端下载代码的逻辑:

如果后台返回的是文件地址,那么前端直接通过 window.location.href 加文件地址,就可以下载文件;

但是如果后台返回的是文件流,那么前端就需要做一些处理;

其实前端处理的核心:就是将文件流转为文件,然后再模拟点击,实现前者的效果。


前端:

const blob = new Blob([res], {
// 设置返回的文件类型
// type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为msword,excel为excel
type: type
})
// 这里就是创建一个a标签,等下用来模拟点击事件
const a = document.createElement('a')
// 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
const URL = window.URL || window.webkitURL
// 根据解析后的blob对象创建URL 对象
const herf = URL.createObjectURL(blob)
// 下载链接
a.href = herf
// 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
a.download = filename
document.body.appendChild(a)
// 点击a标签,进行下载
a.click()
// 收尾工作,在内存中移除URL 对象
document.body.removeChild(a)
window.URL.revokeObjectURL(herf)
}</pre>


这里用简单的问题:遇到了四个问题:
1.主机被迫连接中断,捕捉异常处理
2.vue 超时处理
3.reset 问题。
4.getOutputStream() has already been called for this response的解决方法,值为空,modelAndView,@ResponseBody都不行

最后的解决方法:

@GetMapping("/t1")
    public void down1(HttpServletResponse response) throws Exception {
        response.reset();
        response.setContentType("application/octet-stream;charset=utf-8");
        response.setHeader(
                "Content-disposition",
                "attachment; filename=test.png");
        try(
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\desktop\\1.png"));
                // 输出流
                BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        ){
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) > 0) {
                bos.write(buff, 0, len);
            }
        }
    }

参考资料和推荐阅读:

[1].https://www.jianshu.com/p/a93348d31d8d
[2].https://www.jianshu.com/p/da23cf7c1653
[3].http://www.wjhsh.net/lteal-p-5199911.html
[4].https://wenku.baidu.com/view/d1e44e4b1db91a37f111f18583d049649b660e9c.html?wkts=1669043878887&bdQuery=Springboot+getOutputStream%28%29+has+already+been+called+for+this+response
[5].https://blog.youkuaiyun.com/weixin_43296313/article/details/125100824

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迅捷的软件产品制作专家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值