Jersey+Vue实现附件下载

Java代码返回文件流

@GET
  @Path("/ftp/download")
  @Secured(loginCheck = false)
  public Response download(@QueryParam("filepath") String filepath) {
    try {
      String name = "";
      if (filepath.contains("http://")) {
        String[] str = filepath.split("/");
        name = str[str.length - 1];
      } else {
        String[] split = filepath.split("_");
        name = split[split.length - 1];
      }

      URL url = new URL(filepath);
      URLConnection urlConnection = url.openConnection();
      return Response
          .ok((StreamingOutput) output -> StreamUtils.copy(urlConnection.getInputStream(), output))
          .header("Content-disposition",
              "attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8"))
/*                    .header("Content-Type",
                            URLConnection.getFileNameMap().getContentTypeFor(filepath))*/
          .header("Cache-Control", "no-cache")
          .build();

    } catch (Exception ex) {
      ex.printStackTrace();
      return Response.status(Response.Status.NOT_FOUND).build();
    }
  }

代码解析:
1.

header("Content-disposition",
              "attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8"))

给响应头设置内容内容类型,文件名

 2.

URL url = new URL(filepath);
      URLConnection urlConnection = url.openConnection();
      return Response
          .ok((StreamingOutput) output -> StreamUtils.copy(urlConnection.getInputStream(), output))

获取网上的文件,将网上的文件流作为输入流拷贝到响应输出流

Vue接受文件流并下载
 

async download(file) {
      // window.location.href = this.url;
      console.log(file)
      console.log('11', this.fileList)
      let { url } = this.fileList.filter(f => f.name === file.name)[0]
      console.log(url)
      var filePath = encodeURIComponent(url);
      if (this.loading) return;
      this.loading = true;
      const res = await axios.get("/ftp/download?filepath=" + filePath, {
        responseType: "blob"
      }).finally(() => {
        this.loading = false;
      });
      if (res.status != 200) {
        this.$message.error("网络请求错误!");
        return;
      }
      // 获取文件名(优先从响应头获取)
      const filename = res.headers['content-disposition'].split('=')[1] || file.name

      const extension = filename.split('.').pop().toLowerCase();

// 定义支持的 MIME 类型映射
      const mimeTypeMap = {
        // Word
        'doc': 'application/msword',
        'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',

        // Excel
        'xls': 'application/vnd.ms-excel',
        'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',

        // PDF
        'pdf': 'application/pdf'
      };

// 获取对应的 MIME 类型
      const fileType = mimeTypeMap[extension];

      console.log(fileType)

// 创建 Blob 对象 自动设置office文件的类型,避免office文件损坏
      const blob = new Blob([res.data], fileType ? { type: fileType } : undefined);

//创建下载链接
      const linkurl = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = linkurl;
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(linkurl);
    },

下载附件的要点:

1.请求加上配置

{
        responseType: "blob"
      }

设置接收的响应值类型,否则导致文件格式损坏,导致打不开

2.office文件最好在创建Blob时指定文件类型,否则也有可能打不开下载的附件

 const blob = new Blob([res.data], fileType ? { type: fileType } : undefined);

3.创建下载链接时,要将下载链接加入document节点树里,不然看不见下载附件提示

//创建下载链接
      const linkurl = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = linkurl;
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(linkurl);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值