feign调用返回文件流

 同样是feign调用,返回结果不同。第一个是ResultEntity, 第二个是InputStream输入流。

下面是第一个feign请求的controller的返回ResultEntity:

 下面是第二个feign请求的controller的返回void:

 serviceImpl方法将file文件类型转化为字节数组,并返回字节数组:

byte[] filebyte = Filebyte(file);
return filebyte;

公共方法:

public static byte[] Filebyte(File file){
        byte[] buffer = null;
        try
        {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            long fileSize = file.length();
            log.info("File size is " + fileSize + " bytes");
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer;
    }

另外一个功能:将多个文件打成zip包,代码如下:

@Slf4j
public class FileToZip {

    private FileToZip(){}

    /**
     * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
     * @param zipFilePath :压缩后存放路径
     * @param fileName :压缩后文件的名称
     * @return
     */
    public static byte[] fileToZip(List<ZipDto> fileList, String zipFilePath, String fileName){
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        File zipPath = new File(zipFilePath);
        File zipFile = new File(zipFilePath + "/" + fileName + ".zip");

        //判断源文件是否存在
        try {
            if (!zipPath.exists()) {
                zipPath.mkdirs();
            }
            //判断压缩后文件是否会重复
            if(zipFile.exists()){
                log.info(zipFilePath + "目录下已存在名字为" + fileName +".zip" +"文件");
            }else{
                log.info(zipFilePath + "目录下不存在名字为" + fileName +".zip" +"文件,开始创建文件。");
                zipFile.createNewFile();
                //获取源文件夹下的所有文件
                if(CollectionUtils.isEmpty(fileList)){
                    log.info("待压缩的文件目录:" + fileList + "里面不存在文件,无需压缩.");
                }else{
                    log.info(zipFilePath + "目录下已存在名字为" + fileName +".zip" +"文件,开始读取文件,写入压缩包。");
                    fos = new FileOutputStream(zipFile);
                    zos = new ZipOutputStream(new BufferedOutputStream(fos), Charset.forName("GBK"));
                    byte[] bufs = new byte[1024*10];
                    for(int i=0; i<fileList.size(); i++){
                        //创建ZIP实体,并添加进压缩包
                        ZipEntry zipEntry = new ZipEntry(new String(fileList.get(i).getName().getBytes("GBK"),"GBK"));
                        zos.putNextEntry(zipEntry);
                        //读取待压缩的文件并写进压缩包里
                        bis = new BufferedInputStream(fileList.get(i).getInputstream(), 1024*10);
                        int read = 0;
                        while((read=bis.read(bufs, 0, 1024*10)) != -1){
                            zos.write(bufs,0,read);
                        }
                    }
                    log.info(zipFilePath + "目录下写入压缩包完毕");
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //关闭流
            try {
                if(null != bis) bis.close();
                if(null != zos) zos.close();
                byte[] filebyte = Filebyte(zipFile);
                // 删除zip文件夹
                zipFile.delete();
                return filebyte;

            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }

    public static byte[] Filebyte(File file){
        byte[] buffer = null;
        try
        {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            long fileSize = file.length();
            log.info("File size is " + fileSize + " bytes");
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer;
    }
}

微服务调用返回文件的问题可以通过使用Feign接口调用来解决。在Feign接口中,可以将文件作为普通参数传递,并将其返回到业务服务中。具体的解决方案如下: 首先,在上下层服务间的Feign接口中定义文件下载的方法。可以使用`@GetMapping`注解来指定下载文件的路径,并使用`@PathVariable`注解来获取文件名作为参数。同时,使用`consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE`来指定接收的媒体类型为文件。 ```java import feign.Response; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient("prometheus-file") public interface FileFeignClient { @GetMapping(value = "/file/api/v1/files/{file_name}", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE) Response downFile(@PathVariable("file_name") String fileName); } ``` 然后,在上层服务中将下层服务的文件返回给前端,实现文件下载功能。可以使用`@GetMapping`注解来指定下载文件的路径,并使用`HttpServletResponse`来获取输出。通过Feign接口调用下层服务的方法,获取文件,并将其写入输出中,实现文件下载。 ```java @GetMapping("/file/download") public void downloadProject(HttpServletResponse httpServletResponse) throws IOException { ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream(); Response feignResponse = fileFeignClient.downFile("file_name"); Response.Body feignBody = feignResponse.body(); feignResponse.headers().forEach((String key, Collection<String> value) -> { httpServletResponse.setHeader(key, ((LinkedList<String>) value).get(0)); }); byte\[\] c = new byte\[1024\]; int length; while ((length = feignBody.asInputStream().read(c)) > 0) { servletOutputStream.write(c, 0, length); } servletOutputStream.flush(); servletOutputStream.close(); } ``` 通过以上的解决方案,可以实现微服务调用返回文件的功能。 #### 引用[.reference_title] - *1* [关于微服务之间的传递问题](https://blog.csdn.net/ABestRookie/article/details/122932690)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spring Boot微服务间文件返回实现](https://blog.csdn.net/guyue35/article/details/104481912)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chainoflove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值