工具篇--Spring-Cloud--feign 通过feign 接口完成文件的下载


前言

通常在spring-boot 项目中,对于文件的下载都是直接调用到对应的服务中,而不是通过feign 接口获取文件;有时我们在对接外部接口时,因为权限等问题,不能直接暴露文件服务,会有一个专门对外的服务进行对接,但是我们又要利用现有的文件服务逻辑,此时可以考虑使用feign 完成文件的获取。


一、feign接口获取文件流程:

我们知道feign 只是通过动态代理为我们构建了http 的请求,显然我们不能通过feign 接口直接把 HttpServletResponse 传过去,因为feign接口服务的提供者,接收到的HttpServletResponse 和我们通过feign 接口传入的压根儿就不是同一个对象,所以此时我们只能在文件服务中返回文件流,然后在将文件流 写入到最开始HttpServletResponse 对象中,最后返回给浏览器,流程大概如下:
在这里插入图片描述

二、文件获取实现

2.1 引入jar:

因为我们是web 服务并且使用了feign 接口所有这个两个jar 依赖是必须要有的:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.2 实现:

(1) feign 接口:

@GetMapping(value = "/osp/download/{id}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
ResponseEntity<Resource> download(@PathVariable("id") String id);

(2)feign 接口服务提供者:
控制器:

import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
 @GetMapping("/osp/download/{id}")
 public ResponseEntity<Resource> ospDownloadFile(@PathVariable String id) throws Exception {
     return xxxService.ospDownloadFile(id);
 }

xxxService 对应自己业务里面的实现;实现类:

 @Override
public ResponseEntity<org.springframework.core.io.Resource> ospDownloadFile(String id) throws Exception {
    // 这里获取自己业务中的文件
    FileRecord fileRecord = fileRecordService.selectCache(id);
    if (null == fileRecord)
        throw new Exception("文件不存在");
    InputStream inputStream = null;
    ByteArrayOutputStream outputStream = null;
    try {
        inputStream = getObjectInputStream(fileRecord.getCodeName());
        outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        byte[] byteArray = outputStream.toByteArray();
        // 读取文件内容
        ByteArrayResource resource = new ByteArrayResource(byteArray);

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" +  java.net.URLEncoder.encode(fileRecord.getName(),"UTF-8"));

        // 返回响应实体
        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
    } finally {
        if (null != inputStream) {
            inputStream.close();
        }
        if (null != outputStream) {
            outputStream.close();
        }
    }

}

(3)对外服务端:
对外服务控制器:

@GetMapping("/file/download/{id}")
public void download(@PathVariable String id,HttpServletResponse response) throws Exception {
    ospFlowService.ospDownLoadFile(id,response);
}

业务实现类:

 @Override
public void ospDownLoadFile(String id,  HttpServletResponse response) throws Exception {
    // feign 接口获取文件流
     ResponseEntity<Resource> fileResponse = remoteFileService.download(id);
     // 设置响应头
     response.setHeader(HttpHeaders.CONTENT_DISPOSITION, fileResponse.getHeaders().get(HttpHeaders.CONTENT_DISPOSITION).get(0));
     response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

     // 从 Feign 响应中获取文件输入流,并写入到 HttpServletResponse 输出流中
     InputStream inputStream = fileResponse.getBody().getInputStream();
     OutputStream output = response.getOutputStream();
     IoUtil.copy(inputStream, output);
     // 将流刷新给到浏览器
     response.flushBuffer();
 }

这里使用cn.hutool.core.io 中的 IoUtil 工具类,有需要的可以引入

 <dependency>
  <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
</dependency>

总结

本文通过feign 接口完成文件的下载。

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值