Feign跨服务调用导出(下载)接口

前言

今天有个需求要跨服务调用一个导出excel的接口,两个服务都在同一注册中心上,所以使用Feign调用较为方便,下面记录一下


Feign调用

Feign调用导出接口的方法的出参不是和提供端的方法出入参一样就可以了,一般我们的导出接口都是无返回,直接将内容输出到response中,所以我们调用导出接口的feignt方法需要使用feign提供的Response来接收响应,如下

Feign方法:

import feign.Response;

/**
* 使用Feign调用导出接口
**/
@RequestMapping(value = "/xxxx", method = RequestMethod.POST,consumes = "application/json;charset=UTF-8")
Response exportOrderList(HttpRequest<JSONObject> request);

Feign端controller方法:

 @PostMapping(value = "/exportOrderList")
    @ResponseBody
    public void exportOrderGatherVoList1(@RequestBody  HttpRequest<JSONObject> request, HttpServletResponse response) throws Exception {
         //调用feign方法,获取响应
        Response resp = orderService.exportOrderList(request);
        String date = LocalDate.now().toString();
        String fileName="订单列表-"+date;
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition",
                "attachment;filename*=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
        Response.Body body = resp.body();
        //将响应转为InputStream输入流
        try (InputStream inputStream = body.asInputStream();
             OutputStream outputStream = response.getOutputStream()) {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024*5];
            int n = 0;
            while (-1 != (n = inputStream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            //获取输入流的长度
            byte[] b = output.toByteArray();
            //将输入流的数据读取到字节数组b中
            inputStream.read(b);
            //将字节数组b中的数据写到响应输出流中
            outputStream.write(b);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("IO流异常", e);
        }
    }    

上面为了方便把处理过程写在了controller层,在实际开发中应该放到业务处理层,下面是我拆分的方法

   //获取InputStream输出流的byte字节数组
   public  static  byte[] getByteArrayForInputStream (InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024*5];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }


   //导出方法
   public static void export(Response resp,HttpServletResponse response,String fileName) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition",
                "attachment;filename*=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
        Response.Body body = resp.body();
        try (InputStream inputStream = body.asInputStream();
             OutputStream outputStream = response.getOutputStream()) {
            byte[] b = getByteArrayForInputStream (inputStream);
            inputStream.read(b);
            outputStream.write(b);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("IO流异常", e);
        }
    }

抽出两个方法后,我们的controller就可以简化成以下代码

    @PostMapping(value = "/exportOrderList")
    @ResponseBody
    public void exportOrderGatherVoList1(@RequestBody @Validated HttpRequest<JSONObject> request, HttpServletResponse response) throws Exception {
                 Response resp = orderService.exportOrderList(request);
                 FeignUtil.export(resp,response,"列表导出");
    }

流程

Feign调用其他服务的导出服务,主要流程是通过Feign的Response来接收提供端导出接口的响应,然后通过resp.body()获取响应体,将响应体通过asInputStream方法转为InputStream 输入流,最主要的过程就是将输入流的内容写入到Feign客户端的response输出流中即可。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Feign是一个用于实现接口代理远程调用的组件。在进行服务调用时,首先需要定义一个Feign接口。这个接口用于声明需要调用的目标服务的方法和参数。接着,通过注解@FeignClient来指定需要调用服务的名称。例如,使用@FeignClient("coupon-template-service")来指定调用coupon-template-service服务。然后,可以在接口中使用@GetMapping或@RequestMapping等注解来指定具体的请求路径和参数。最后,通过在方法上添加@RequestParam或@RequestBody等注解来传递参数。这样就完成了Feign服务调用配置。 Feign服务调用是通过动态代理实现的,它会根据接口的定义在运行时动态生成代理类,并通过代理类来发起远程调用。因此,在实际调用时,我们只需要像调用本地方法一样调用Feign接口的方法即可。总结起来,Feign服务调用的具体步骤为:1) 定义Feign接口;2) 使用@FeignClient注解指定调用服务名称;3) 在接口中定义具体的请求路径和参数;4) 通过注解传递参数;5) 调用Feign接口的方法来发起远程调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [使用 OpenFeign 实现服务调用](https://blog.csdn.net/weixin_40364776/article/details/128696456)[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^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [怎样使用feign进行远程调用其他服务](https://blog.csdn.net/qq_55278081/article/details/126308889)[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^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Spring boot2X Consul如何使用Feign实现服务调用](https://download.csdn.net/download/weixin_38602982/12744704)[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^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值