【Java】下载接口回传的文件(附代码)

前言

最近遇到一个需求是这样的,我需要使用Feign去调用一个外部接口,以下就称该接口为api吧,这个api调用后是获取指定ip暴露的地址,携带参数去访问这个接口后,在客户端浏览器就会自动下载文件。

简单来说,就是访问一个URL然后浏览器就下载文件。

假如?

假如我想要在服务器截获这个文件呢?首先,这个需求明确的想要拿到这个文件,并保存服务器以供后续的操作,但是现在访问这个api接口却只能客户端下载,那我总不能去再写一个上传模块然客户端下载后去上传吧,这不现实。

方案一:

有的会说了,让对方把接口改掉,改变成以附件的形式传过来不就可以了吗?但是,这是需要远程调用的第三方接口,由于有些接口是诸如涉密平台,或者无法要求对方做出适配性改变的,那完蛋了,改变不了对方,遂放弃此方案。

方案二:

既然改变不了对方,那么我们只能改变我们自己了(卑微)。

首先,我们在本地环境可能不太好模拟出下载文件的场景,所以动手写一个实现一个访问接口,打开本地文件方式,并且可以在浏览器自动下载。以下你只需要把filePath填好你自己的文件绝对路径即可打开。

第一步

@GetMapping("/api/getFile")
public void downloadFile(HttpServletResponse response) throws IOException {
   String filePath = "E:\\flyz\\test\\test-pdf.pdf"; //这里填入你的本地文件地址
   File file = new File(filePath);
   // 设置响应头,使浏览器能够开始下载文件
   response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
   response.setContentType("application/octet-stream");

   // 将文件内容写入响应输出流
   try (InputStream inputStream = new FileInputStream(file);
       BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
      int bytesRead;
      byte[] buffer = new byte[1024];
      while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
         response.getOutputStream().write(buffer, 0, bytesRead);
      }
   }

   response.getOutputStream().flush();
}

ok!有了上述的基础实现,之后呢比如我已经打开我本地的服务了,暴露的ip和端口是http://localhst:8088/admin/api/getFile, 当我访问这个端口后浏览器就会去路径下载test-pdf.pdf这个文件,只要把这个路径当作远程调用的路径输入做测试即可。

那么进入第二步

现在我要截取这个文件,并保存到我本地怎么实现呢?

@GetMapping("/api/callFeign")
public void callFeign() throws IOException {
   String fileContentUrl = "***"; 
   // 生成保存文件的路径
    //自定义一个保存文件路径
   String saveFilePath = "E:\\flyz\\save\\file.pdf";

   // 下载文件并保存到本地
   try (InputStream inputStream = 
   				new URL(fileContentUrl).openStream();
      FileOutputStream outputStream = new FileOutputStream(saveFilePath)) {
      byte[] buffer = new byte[1024];
      int bytesRead;
      while ((bytesRead = inputStream.read(buffer)) != -1) {
         outputStream.write(buffer, 0, bytesRead);
      }
   } catch (IOException e) {
      // 处理下载文件失败的情况
      // ...
   }
}

这里fileContentUr就是填入你调用外部接口下载文件的地址,直接将你第一步的接口路径(http://localhst:8088/admin/api/getFile,)赋给fileContentUrl这个变量,而后调用,即可在saveFilePath这个自定义的保存路径上面查看到已经下载的文件了。

但是,这样也还不够,为了多加一条测试,可以打开Minio,上传一个文件后,将这个文件的分享下载路径导出,赋给fileContentUrl,再访问,也可以正常的截取到这个文件流,并下载在指定文件夹路径中而不会在浏览器上下载。
在这里插入图片描述
在这里插入图片描述

结语

自此,文件流截取下载也算是小试牛刀了!但是考虑到若不使用Feign而使用上述方式,在海量用户多线程的访问下,该方法的可靠性和稳定性肯定是大打折扣的,所以该种方式仍需要根据实际需求而定。而且图中将代码放置在控制层仅仅是为了方便,最好还是规范一点放在服务层,保存文件后一般需要同步存储逻辑到数据库当中,少不了CRUD,所以最好是在服务层写代码并确定好事务,以及异常回滚等。

若有使用PageOffice的,想必也有需要word转换成pdf文件的需求,可以参考我的下一篇基于com.aspose.words实现的转换方法,代码量非常少,通俗易懂。

PageOffie的使用过程仍有一些细节可以帮你避开坑,详情请查看关于PageOffice你要知道的一些细节及避坑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值