文章目录
对接第三文件下载接口,通过restTemplate或java执行linux的cmd指令完成
1.业务场景
与其他第三方通过restful接口对接,需调用第三方文件下载接口。
这里有两个思路,一种是用http client调用第三方接口进行文件下载。另一种可以通过java执行系统(linux)的cmd指令,进行文件下载,从而实现对下载文件的管理。
2.通过restTemplate.exhcange()方法下载文件
// 1.请求下载文件接口
HttpHeaders headers = new HttpHeaders();
headers.add("content-type", "application/x-www-form-urlencoded");
RestTemplate restTemplate = new RestTemplate();
String id = "id123";
String invalid = "in123";
ResponseEntity<byte[]> entity = restTemplate.exchange(
"localhost:8080/download?id=${id}&invalid=${invalid}",
HttpMethod.POST,
new HttpEntity<>(headers),
byte[].class,
id,
invalid);
// 2.获取二进制数据,写入inputStream
byte[] bytes = entity.getBody();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
// 3.从heads中获取fileName,在获取文件名称时需进行预防空指针
List<String> list = entity.getHeaders().get("content-disposition");
String fileName = list.get(0).split("filename=")[1];
// 4.通过outputStream返数据
String agent = request.getHeader("USER-AGENT");
log.info("[ndss] request's agent is :{}", agent);
try {
// 设置heads
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "inline;filename=" + fileName);
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
OutputStream fos = response.getOutputStream();
byte[] b = new byte[1024];
int length;
while ((length = inputStream.read(b)) > 0) {
fos.write(b, 0, length);
}
fos.flush();
inputStream.close();
fos.close();
return ResponseEntity
.ok()
.headers(headers)
.body("下载成功");
} catch (Exception e) {
log.error("文件下载出错,错误信息:{}", e.toString());
return ResponseEntity
.ok()
.body("文件下载失败。");
}
3.通过java调用linux指令进行文件下载
主要思路是通过服务器的curl指令请求第三方接口进行文件下载。
通过java调用linux的cmd指令,通过curl调用文件下载接口,可以将文件下载本地,再读取本地文件进行操作。
核心代码如下:
private void executeLinuxCmd(String cmd) {
System.out.println("got cmd job : " + cmd);
Runtime run = Runtime.getRuntime();
try {
Process process = run.exec(cmd);
InputStream in = process.getInputStream();
BufferedReader bs = new BufferedReader(new InputStreamReader(in));
StringBuffer out = new StringBuffer();
byte[] b = new byte[8192];
for (int n; (n = in.read(b)) != -1; ) {
out.append(new String(b, 0, n));
}
log.info("execute cmd job result:[ +{}+]", out.toString());
in.close();
process.destroy();
} catch (IOException e) {
log.error("execute cmd job err:{}", e.toString());
}
}
4.WebClient
在翻阅restTemplate文档时,看到这么一段话。
As of Spring Framework 5, alongside the WebFlux stack, Spring introduced a new HTTP client called WebClient.
WebClient is a modern, alternative HTTP client to RestTemplate. Not only does it provide a traditional synchronous API, but it also supports an efficient nonblocking and asynchronous approach.
That said, if we're developing new applications or migrating an old one, it's a good idea to use WebClient. Moving forward, RestTemplate will be deprecated in future versions.
Spring Framework 5开始,引入了新的http client工具–webClient,特点是支持异步。webClient的使用后续再进行梳理。