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

本文介绍了在Feign客户端如何处理从服务间通过`/PersonInfoController/stream`接口获得的纯文本流数据,包括设置响应头、接收流内容并将其转换为JSON对象的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务通过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;
        }
    }
您可以使用Feign调用下载接口。首先,确保您已经在项目中引Feign的依赖。 接下来,创建一个接口,定义下载接口的方法。例如: ```java @FeignClient(name = "download-service") public interface DownloadClient { @RequestMapping(value = "/download", method = RequestMethod.GET) void downloadFile(@RequestParam("fileUrl") String fileUrl, HttpServletResponse response); } ``` 在上述代码中,`@FeignClient`注解指定了下载服务的名称,`@RequestMapping`注解定义了下载接口的请求路径和方法,`downloadFile`方法用于触发下载操作。 然后,使用该接口进行调用。例如,在某个服务中需要下载文件时,可以通过依赖注的方式使用`DownloadClient`接口,然后调用`downloadFile`方法: ```java @RestController public class MyController { @Autowired private DownloadClient downloadClient; @GetMapping("/my-download") public void downloadFile() { // 调用下载接口 downloadClient.downloadFile("http://example.com/file.pdf", response); } } ``` 在上述代码中,通过`downloadClient.downloadFile`调用下载接口,并传文件的URL和`HttpServletResponse`对象,该对象用于返回文件给客户端。 需要注意的是,Feign默认使用的是Spring MVC,因此可以直接使用Spring MVC的注解来定义请求路径和方法。 希望以上信息能对您有所帮助!如果还有其他问题,请随时提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值