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

文章目录

  • 前言
  • 一、feign接口获取文件流程:
  • 二、文件获取实现
    • 2.1 引入jar:
    • 2.2 实现:
  • 总结


前言

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


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

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

二、文件获取实现

2.1 引入jar:

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

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
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=" + fileRecord.getName());

        // 返回响应实体
        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.hutoolgroupId>
    <artifactId>hutool-allartifactId>
dependency>

总结

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

你可能感兴趣的:(java工具篇,#,spring-cloud,spring,java)