spring boot -+- httpclient訪問api -+-下載pdf文件 總結
阿新 • • 發佈:2019-01-01
今天專案上做了一個需求,請求別服務的下載介面,但是不能直接去訪問,要寫一個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");
}
這個檔案下載的程式碼沒什麼說的了,看程式碼應該能看懂的
歡迎各位看官發表看法,互相學習。