RestTemplate 下载第三方接口Zip文件,并读取文件中需要的内容,把zip中的文件提供给前端下载
业务场景:
项目中使用 restTemplate 调用第三方提供的接口,该接口是下载 zip文件,里面有多个pdf文件。restTemplate 使用 byte[] 接收文件,然后需要把其中zip压缩内容中的 pdf 文件读取出来,并返回给前端下载 pdf文件。
1. 读取下载的文件
byte[] bytes = null;
InputStream inputStream = null;
ZipInputStream zipInputStream = null;
ServletOutputStream out = null;
try {
// 这里是通过resttemplate 调用第三方接口下载对方提供的zip文件
bytes = httpClientCommon.downLoad(downloadRequest);
inputStream = new ByteArrayInputStream(bytes);
zipInputStream = new ZipInputStream(inputStream);
out = response.getOutputStream();
// 这里只需要读取第一个文件。如果需要读取多个就用while
ZipEntry zipEntry = zipInputStream.getNextEntry();
String zipEntryFileName = zipEntry.getName();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLUtil.encode(zipEntryFileName));
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain");
while (zipEntry != null) {
byte[] buff = new byte[1024];
int len = -1;
//开始边读边写
while ((len = zipInputStream.read(buff)) != -1) {
out.write(buff, 0, len);
}
out.flush();
break;
}
} catch (Exception e) {
...
}
1.2 restTemplate 调用第三方接口下载ZIP文件
public byte[] downLoad(EleBaseRequest request) {
final ObjectMapper mapper = new ObjectMapper();
final Field[] fields = request.getClass().getDeclaredFields();
String url = properties.getHost() +
request.getInterfaceEnum().getPath() +
"?" +
Arrays.stream(fields).filter(e -> {
try {
e.setAccessible(true);
return e.get(request) != null;
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}).map(e -> {
e.setAccessible(true);
try {
return e.getName() + "=" + mapper.writeValueAsString(e.get(request)).trim().replaceAll("\"","");
} catch (JsonProcessingException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}).collect(Collectors.joining("&"));
// 设置请求头
HttpHeaders httpHeaders = setHeader(request.getInterfaceEnum().getMediaType());
final HttpEntity<Object> httpEntity = new HttpEntity<>(httpHeaders);
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(
url,
HttpMethod.GET,
httpEntity,
byte[].class);
return responseEntity.getBody();
}
2. 调用第三方下载接口,把数据原样返回给前端下载(不读取ZIP 内的文件)
调用的第三方接口是返回的zip文件,这里restTemplate 使用 byte[] 接收文件。
try {
// 第三方接口返回的zip文件
byte[] bytes = httpClientCommon.downLoad(downloadRequest);
inputStream = new ByteArrayInputStream(bytes);
String fileName = "attachment;fileName=" + contractPO.getId() + ".zip";
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
response.setHeader("Content-Disposition", fileName);
byte buff[] = new byte[1024];
int length = 0;
while ((length = inputStream.read(buff)) > 0) {
out.write(buff, 0, length);
}
out.flush();
} catch (Exception e) {
log.error("下载异常:{} ,{} ", id, e.getMessage());
throw new ApplicationException(CONTRACT_DOWNLOAD_FAIL);
} finally {
if (out != null) {
out.close();
}
if (inputStream != null) {
inputStream.close();
}