SpringBoot 阿里云oss实现文件下载

前端采用的是vue和axios

 后端关键点:

response.setHeader("Content-Disposition", "attachment;filename=" + new String(objectName.getBytes(),  "ISO-8859-1"));

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

 后端全部代码:

    /**
     * 下载文件
        //objectName是文件全名称,如"图片.png"
     */
    @GetMapping("/downLoad")
    public void downLoad(@RequestParam("key") String objectName, 
                         HttpServletResponse response) throws UnsupportedEncodingException {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        //通知浏览器以附件形式下载,(必要的配置!!!!!)
        response.setHeader("Content-Disposition",
         "attachment;filename=" + new String(objectName.getBytes(), 
             "ISO-8859-1"));

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

        try {
            // 调用ossClient.getObject返回一个OSSObject实例,该实例包含文件内容及文件元数据。
            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
            // 调用ossObject.getObjectContent获取文件输入流,可读取此输入流获取其内容。
            InputStream fis = ossObject.getObjectContent();

            //获取缓冲输出流
            OutputStream fos = response.getOutputStream();
            BufferedOutputStream bos = new BufferedOutputStream(fos);

            //开始发送数据
            byte[] buffer = new byte[1024];
            int length = 0;
            while ((length = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, length);
            }
            if (bos != null) {
                bos.flush();
                bos.close();
            }
            if (fis != null) {
                fis.close();
            }

        } catch (OSSException oe) {
          //..............处理错误
        } catch (ClientException ce) {
          //..............处理错误
        } catch (IOException ex) {
           //..............处理错误
        } finally {
           //关闭资源
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

    }

 前端关键点:

axios的请求中    

    timeout: "0",
//我的项目中,如果不把超时时间设置成无限,会导致文件没下载不完全
    responseType: 'blob'
//返回类型设置成流传输

参考axios文档:{
  // `responseType` 表示浏览器将要响应的数据类型
  // 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
  // 浏览器专属:'blob'
  responseType: 'json', // 默认值
}

 前端请求完整代码: (用的是Elemnet Plus)

const handleDownLoad = (index: number, row: File) => {
  request({
    url: "/downLoad",
    method: "GET",
    timeout: "0",
    params: {
      key: row.key//row.key是文件的全名称
    },
    responseType: 'blob'//必要的设置
  }).then((res) => {
/**
    以下代码是为了让浏览器下载器中显示文件下载完成
    不太清楚原理...
*/

    let blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;"});
    // 为blob设置文件类型,这里以.xlsx为例
    let url = window.URL.createObjectURL(blob); 
    // 创建一个临时的url指向blob对象
    let a = document.createElement("a");
    a.href = url;
    a.download = row.key;
    a.click();
    // 释放这个临时的对象url
    window.URL.revokeObjectURL(url);
   

  })
}

 

    <el-table :data="files" style="width: 100%" v-loading="loading">
      <el-table-column label="上传时间" width="380">
        <template #default="scope">
          <div style="display: flex; align-items: center">
            <el-icon>
              <timer/>
            </el-icon>
            <span style="margin-left: 10px">{{ scope.row.modifiedTime }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="文件名" width="380">
        <template #default="scope">
          <div style="display: flex; align-items: center">
            <span style="margin-left: 10px">{{ scope.row.key }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="文件大小" width="380">
        <template #default="scope">
          <div style="display: flex; align-items: center">
            <span style="margin-left: 10px">{{ (scope.row.size / (1024 * 1024)).toFixed(2) }}MB</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template #default="scope">
          <el-button size="small" type="primary" @click="handleView(scope.$index, scope.row)">在线预览</el-button>
          <el-button size="small" type="success" @click="handleDownLoad(scope.$index, scope.row)"
                     element-loading-text="Loading...">下载
          </el-button>
          <el-button
              size="small"
              type="danger"
              @click="handleDelete(scope.$index, scope.row)">删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

成功截图:

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
阿里云提供了Java SDK,通过该SDK,我们可以方便地在springboot中集成阿里云oss服务,实现文件的上传、下载、删除等操作。具体步骤如下: 1. 引入阿里云oss SDK依赖 ```xml <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>2.6.1</version> </dependency> ``` 2. 在application.properties中配置oss相关参数 ```properties # oss访问地址 aliyun.oss.endpoint=yourEndpoint # oss访问的accessKeyId aliyun.oss.accessKeyId=yourAccessKeyId # oss访问的accessKeySecret aliyun.oss.accessKeySecret=yourAccessKeySecret # oss的bucket名称 aliyun.oss.bucketName=yourBucketName ``` 3. 编写oss工具类,实现文件的上传、下载、删除等操作 ```java @Service public class OSSUtil { @Autowired private OSSClient ossClient; // 上传文件 public void uploadFile(String key, InputStream inputStream) { ossClient.putObject(bucketName, key, inputStream); } // 下载文件 public void downloadFile(String key, OutputStream outputStream) { OSSObject ossObject = ossClient.getObject(bucketName, key); InputStream inputStream = ossObject.getObjectContent(); try { byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // 删除文件 public void deleteFile(String key) { ossClient.deleteObject(bucketName, key); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值