今天项目上做了一个需求,请求别服务的下载接口,但是不能直接去访问,要写一个controller中转一下,为了能做权限控制;用了springboot,httpclient相关技术,实现这个功能分几步我简单说一下:
1.写一个controller(接口) ,给前端请求
2.通过 httpclient 转发到别的服务的 url
3.获取httpclient 的流,并写入到目标路径(储存)
4.从 目标路径获取文件流 以完成下载(如果需要的话)
下面来一步一步的说:
1.Controller:控制层就是要把这几个功能包装起来咯,看代码:
@ApiOperation(value = "获取pdf", notes = "获取pdf", consumes = "application/pdf")
@PostMapping(path = "getPdf")
public void getPdf(@RequestBody AppScanInput appScanInput, HttpServletResponse response) {
//默认下载路径(这个路径很好理解)
String classpath = SecurityScanController.class.getClassLoader().getResource("").getPath();
String saveFilePath = classpath + "pdf/" + appScanInput.getName() + ".pdf";
//判断文件是否已经存在,不存在的话,写httpclient去调下载接口
File file =new File(saveFilePath);
if (!file.exists()) {
//从别的服务下载pdf文件到此服务
downLoadPdfInSystem(saveFilePath, appScanInput);
}
//此服务下载到客户端
pdfDownload(response, appScanInput);
}
注意:这里是从别的服务下载pdf文件到此服务,,再从此服务下载到客户端,are you 明白?
上面的注解是swaggerUI的相关注解,注意这个 consumes = "application/pdf",别的没啥好说2.通过 httpclient 转发到别的服务的 url
private void downLoadPdfInSystem (String path, AppScanInput appScanInput) {
//别的服务的下载接口url
String url_down_pdf = UrlConstants.domainUrl_test + UrlConstants.url_down_pdf;
//参数封装 流的初始化
Map<String, Object> params = new HashMap<>();
File f = new File(path);
InputStream in = null;
String scanType = appScanInput.getType();
try {
params.put("scan_type", scanType);
params.put("hash", appScanInput.getAa());
//httpclient发送POST请求,注意看这里比较重要,doPost是一个方法,我贴在下面了。。。
HttpEntity httpEntity = HttpUtil.doPost(url_down_pdf, params);
//从返回的httpEntity中获取输入流
in = httpEntity.getContent();
//写文件的代码,不多说
OutputStream os = new FileOutputStream(f);
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2.HttpClient发送请求的方法: 返回的是一个HttpEntity(接口返回的东西都在这里)
public static HttpEntity doPost(String url, Map<String, Object> param) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Authorization", ConstPojo.Authorization);
HttpEntity httpEntity;
//设置请求和连接超时时间
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000 * 60).setConnectTimeout(1000 * 60).build();
httpPost.setConfig(requestConfig);
try {
if (null != param) {
// 设置参数
if (CommonUtil.isNotEmptyMap(param)) {
UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(setHttpParams(param), "UTF-8");
httpPost.setEntity(encodedFormEntity);
}
}
CloseableHttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("statusCode:"+statusCode);
if (statusCode == 200) {
Header[] allHeaders = response.getAllHeaders();
httpEntity = response.getEntity();
System.out.println(allHeaders.toString());
System.out.println(httpEntity.toString());
return httpEntity;
} else {
System.out.println("连接异常。。。");
}
} catch (Exception e) {
// TODO ...
e.printStackTrace();
}
return null;
}
3.获取httpclient 的流,并写入到目标路径(储存)
。。。。。。没东西写了,第三步的东西,都在第二部的代码里了,pass
4.从 目标路径获取文件流 以完成下载(如果需要的话)
这个就是
pdfDownload(response, appScanInput)这个方法了
public void pdfDownload(HttpServletResponse res, AppScanInput appScanInput) {
String fileName = appScanInput.getName() + ".pdf";
//设置头信息
res.setHeader("content-type", "application/octet-stream");
res.setContentType("application/octet-stream");
res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
byte[] buff = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
String classpath = SecurityScanController.class.getClassLoader().getResource("").getPath();
String saveFilePath = classpath + "pdf/" + appScanInput.getName() + ".pdf";
try {
os = res.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(new File(saveFilePath)));
int i = bis.read(buff);
//防止中文乱码
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// System.out.println("success");
}
这个文件下载的代码没什么说的了,看代码应该能看懂的
欢迎各位看官发表看法,互相学习。