下载文件接口学习

本文介绍了一种在Java Web环境中实现文件下载的方法,通过HttpServletResponse的outputStream返回二进制流,设置Content-Type为application/octet-stream,实现了从浏览器下载文件的功能。文章详细展示了代码实现过程,并分享了在实践中遇到的问题及解决办法。

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

1.达到目的:生成一个URL,将URL放到浏览器上,enter后可下载文件

2.实现关键:

   ①通过HttpServletResponse response的outputStream返回二进制流;   

   ②response.setContentType("application/octet-stream")

3.实现代码:


public void upload(HttpServletRequest request, HttpServletResponse response) {
    // 获取参数,GET和POST均可以
    String param1 = request.getParameter("param1");
    String param2 = request.getParameter("param2");
    if ((null == param1 || param1.isEmpty()) || (null == param2 || param2.isEmpty())) {
        logger.error("error params!");
        return;
    }

    logger.info("params: param1: {}, param2: {}", param1, param2);

    InputStream inputStream = null;
    OutputStream outputStream = null;
    try {
        inputStream = getStream(); // 在后台获取文件流

        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("upload.jpg", "UTF-8"));
        response.setContentType("application/octet-stream");  // 用于下载的二进制流类型
        outputStream = response.getOutputStream();

        // 写入输出流
        byte[] buffer = new byte[1024];
        int len;
        while((len = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, len);
        }

        outputStream.flush();
        // outputStream.close(); 这里不可以关,会产生Broken pip异常,一旦关闭,其他人将无法读取
    } catch (Exception e) {
        logger.error("failed to get pictures, the reason is ", e);
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
            }
        }

        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
            }
        }
    }
}

// 获取文件流,这里只是举了个例子,也可以是从别的地方获取的文件流
private InputStream getStream() throws FileNotFoundException {
    String fileName = "D:/test.PNG";

    FileInputStream inputStream = new FileInputStream(new File(fileName));

    return inputStream;
}

4.遇到的坑

①response的contentType

        一开始查到的样例,使用的是 image/png,发现可以从浏览器读取到图片,但是无法下载,后来百度发现这种格式主要用于html元素展示;后改为application/octet-stream(二进制流格式),可以下载。

具体的contentType,这一篇讲的想对详细,可查看:https://blog.youkuaiyun.com/qq_37651267/article/details/91380351

②可以下载后,因为对流的处理不是很熟悉,导致出现两类错误,虽然其中一类并不是代码原因导致

       1)IOException:Broken pip,这个问题是因为我在outputStream写完后就关了,导致没有办法访问到,虽然我仍然有疑惑的点是,1> 放在finally,还是有可能关掉,但是目前代码执行上看来,这样写并没有问题,2> 我也看到工具类中是可以选择不关闭流的,由使用者关闭,但是若使用者未及时关闭,不会导致连接过多,后面的无法连接么?

       2)IOException:Connection reset by peer,这个问题简单来说是客户端主动关闭了连接,我这边出现的问题是,因为我这边需要经过网关,但网关对应存储的磁盘快满了,导致大一点的文件写入都会报错,但小一点的文件就不会有问题,这一点也提醒我们需要关注网关本身对传输文件大小的限制以及网关对应存储硬件对传输文件大小的限制

③如果客户端可以通过一个专门的文件接口获取资源,比如OSS提供的接口,最好不要将这类接口与自身服务接口混淆一起,减少网关的压力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值