【服务通过Feign调用文件下载接口获取响应数据,返回类型为void,入参只有HttpServletResponse】

服务通过Feign调用文件下载接口获取响应数据,返回类型为void,入参只有HttpServletResponse:

问题描述

做项目以来一直是调用对应调用外部其他服务的文件接口,现在要进行服务内部调用其他服务的,遇到这种情况还真没有处理过这种情况。

被调用方服务提供的接口

@Slf4j
@RestController
@RequestMapping("/PersonInfoController")
@RequiredArgsConstructor
public class PersonInfoController {
    private final UaPersonInfoService uaPersonInfoService;
    private final FileOperate fileOperate;

    @GetMapping("/stream")
    public void stream(HttpServletResponse response) throws IOException {
        // 设置响应的内容类型为纯文本
        response.setContentType("text/plain");
        // 设置字符编码
        response.setCharacterEncoding("UTF-8");
        // 设置响应头,开启流模式(chunked transfer encoding)
        // 启用了分块传输编码,这允许服务器将响应分成多个部分,并在准备好每个部分时发送它,而不是等待整个响应完成
        response.setHeader("Transfer-Encoding", "chunked");

        fileOperate.writeText(uaPersonInfoService.listPersonInfo())
                .delimiter("|")
                .write(response.getOutputStream());
    }

feign调用方写法
对应服务之间的调用若不是通过客户端发送的请求,服务之间是HttpServletResponse和HttpServletRequest的入参,可以不传,对应用response响应进行流输出的接口,在进行feign调用时可以将返回类型写成ResponseEntity<byte[]>或者Response进行byte字节接收。

@FeignClient(value = "system-user-executor",path = "/system-user-executor")
public interface SystemUserExecutorFeign {

    /**
     * 获取数据
     * @return
     */
    @GetMapping("/PersonInfoController/stream")
    ResponseEntity<byte[]> stream () throws IOException;
}

业务逻辑代码处

try {
            ResponseEntity<byte[]> response = systemUserExecutorFeign.stream();
            log.info("验证有无数据");
            byte[] fileResult = response.getBody();
            if(fileResult!=null){
                InputStream inputStream = new ByteArrayInputStream(fileResult);
                List<PersonInfoRsp> rspList = fileOperate.readText(PersonInfoRsp.class, inputStream).delimiter("|")
                        .read();
                log.info("看看转出来没有"+rspList);
                System.out.println("看看转出来没有+rspList");
                //插入表逻辑待写
            }
        }catch (IOException ioException){
            log.info("IO流传输异常{}",ioException.getMessage(),ioException);
        }

对应调用外部有json规范的文件流接口
可以采用spring自带的RestTemplate进行发送内容获取,转成json对象

private Result getFileData(String fileName, int type) {
        Result result = new Result();
        JSONObject data = new JSONObject();
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            ResponseEntity<byte[]> response = restTemplate.exchange(fileName, HttpMethod.GET, new HttpEntity<byte[]>(headers), byte[].class);
            byte[] fileResult = response.getBody();
            if (fileResult == null) {
                result.setSuccess(false);
                result.setMsg("文件无数据");
                return result;
            }
            InputStream inputStream = new ByteArrayInputStream(fileResult);
            // 如果是2007以上的版本创建的Excel文件,一定要用XSSF
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            // 读取第一个Sheet
            XSSFSheet sheet = workbook.getSheetAt(0);
            // 循环读取每一行
            List<Object> list = new ArrayList<>();
            //sheet.getLastRowNum()
            for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                JSONObject cellData = new JSONObject();
                for (int cellNum = 0; cellNum < sheet.getRow(rowNum).getLastCellNum(); cellNum++) {
                    String stringCellValue = sheet.getRow(rowNum).getCell(cellNum).getStringCellValue();
                    String mapKey = "";
                    if (type == 1) {
                        //组织数据
                        if (cellNum == 0) {
                            mapKey = "id";
                        } else if (cellNum == 1) {
                            mapKey = "name";
                        } else if (cellNum == 2) {
                            mapKey = "orgId";
                        } else if (cellNum == 3) {
                            mapKey = "orgName";
                        } else if (cellNum == 4) {
                            mapKey = "orgType";
                        } else if (cellNum == 5) {
                            mapKey = "parentOrg";
                        } else if (cellNum == 6) {
                            mapKey = "level";
                        }
                    } else if (type == 2) {
                        //人员数据
                        if (cellNum == 0) {
                            mapKey = "id";
                        } else if (cellNum == 1) {
                            mapKey = "phone";
                        } else if (cellNum == 2) {
                            mapKey = "customerId";
                        } else if (cellNum == 3) {
                            mapKey = "name";
                        } else if (cellNum == 4) {
                            mapKey = "orgId";
                        } else if (cellNum == 5) {
                            mapKey = "orgName";
                        } else if (cellNum == 6) {
                            mapKey = "orgType";
                        }
                    }
                    cellData.put(mapKey, stringCellValue);
                }
                cellData.put("status", "ACTIVE");
                list.add(cellData);
                // 读取该行第0列的元素,用getRow().getCell得到的是一个Cell对象
            }
            data.put("dataList", list);
            result.setSuccess(true);
            result.setMsg("success");
            result.setData(data);
            return result;
        } catch (Exception e) {
            log.error("文件获取失败{}",e.getMessage(),e);
            e.printStackTrace();
            result.setSuccess(false);
            result.setMsg("获取文件数据失败");
            return result;
        }
    }
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在使用Feign调用服务时,如果想取消响应数据映射,直接以String类型返回,可以通过在Feign的配置类上加上`Decoder`和`Encoder`的Bean实现。具体操作如下: 1. 创建一个配置类,例如`FeignConfig`,并在该类上加上注解`@Configuration`。 2. 在配置类中定义一个`Decoder`类型的Bean,用于取消响应数据映射,直接以String类型返回。具体代码如下: ```java @Bean public Decoder feignDecoder() { return new Decoder() { @Override public Object decode(Response response, Type type) throws IOException, FeignException { if (type.equals(String.class)) { return Util.toString(response.body().asReader()); } else { return new JacksonDecoder().decode(response, type); } } }; } ``` 3. 在配置类中定义一个`Encoder`类型的Bean,用于将请求数据转换为String类型。具体代码如下: ```java @Bean public Encoder feignEncoder() { return new Encoder() { @Override public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException { if (bodyType.equals(String.class)) { template.body(object.toString(), Charset.defaultCharset()); } else { new JacksonEncoder().encode(object, bodyType, template); } } }; } ``` 4. 最后,在Feign客户端接口上加上注解`@FeignClient`,并指定配置类`FeignConfig`,即可实现取消响应数据映射,直接以String类型返回。例如: ```java @FeignClient(name = "microservice", configuration = FeignConfig.class) public interface MicroserviceClient { @GetMapping("/api/data") String getData(); } ``` 以上就是使用Feign调用服务,取消响应数据映射,直接以String类型返回的方法。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值