服务通过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;
}
}