Java使用HttpClient模擬http(登入、請求資源並二次處理)栗子
阿新 • • 發佈:2019-01-03
在工作中遇到過在一個伺服器應用(A)上去請求另一個伺服器應用(B)上的資源,然後在A中去二次處理該資源的問題,其實追根到底,就是一次cp的操作。
因為B應用是一個第三方的應用,只能通過使用http請求的方式去獲取其上的資源。
做個簡單的示意圖:
接下來上程式碼:
首先,模擬登陸記錄 :
public CloseableHttpClient login(String loginUrl, String id, String pw) { CloseableHttpClient httpClient = HttpClients.createDefault(); // 使用的是post請求方法 HttpPost httPost = new HttpPost(loginUrl); // 設定請求引數 List<NameValuePair> nvp = new ArrayList<>(); // 使用者名稱 nvp.add(new BasicNameValuePair("id", id); // 密碼 nvp.add(new BasicNameValuePair("pw", pw)); /** * 以及其他引數 。。。 */ try { // 將請求引數放入到post entity中 httPost.setEntity(new UrlEncodedFormEntity(nvp, Constants.sCharSet)); String html = httpClient.execute(httPost, responseHandler); if("".equals(html)) { logger.info("登入成功!"); } else { logger.warn("登入失敗!"); } } catch (UnsupportedEncodingException e) { logger.error("設定post請求引數出錯!", e); } catch (ClientProtocolException e) { logger.error("ClientProtocolException 登入請求出錯!", e); } catch (IOException e) { logger.error("IOException 登入請求出錯!", e); } finally { httPost.abort(); } return httpClient; }
登陸成功後,會返回一個CloseableHttpClient 物件。並終止這次請求
httPost.abort();
接下來就是請求資源了,可根據應用B的介面型別,選擇相應的請求型別[get/post]
/** * 下載並複製檔案 */ pubic JSONObject copyFile(CloseableHttpClient httpClient, String fileId, String getUrl, String name, String bApplicationUrl) { HttpPost httPostDownload = new HttpPost(getUrl); // 下載檔案流 InputStream inputStream = null; // copy檔案流 OutputStream outputStream = null; // 返回物件 JSONObject fileJson = new JSONObject(); try { List<NameValuePair> nvpDownload = new ArrayList<>(); nvpDownload.add(new BasicNameValuePair("action", "query")); nvpDownload.add(new BasicNameValuePair("id", fileId)); // 其他引數 。。。 httPostDownload.setEntity(new UrlEncodedFormEntity(nvpDownload, Constants.sCharSet)); // 傳送查詢檔案資訊 -》 返回 檔案路徑和下載地址 HttpResponse httpResponseQuery = httpClient.execute(httPostDownload); HttpEntity httpEntityQuery = httpResponseQuery.getEntity(); if (httpEntityQuery != null) { // 獲取返回的檔案資訊 JSONObject jsonObject = this.getFileInfo(httpEntityQuery); String fileDownloadUrl = jsonObject.getString("fileDownloadUrl"); //下載檔案 String url = bApplicationUrl + "/" + fileDownloadUrl; HttpGet httpGetDownload = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGetDownload); HttpEntity httpEntityDownload = httpResponse.getEntity(); inputStream = httpEntityDownload.getContent(); //copy 檔案到A所在伺服器 // 檔案路徑和字尾 String cpFilePath = Constants.COPY_FILE_PATH + "/" + name + Constants.FILE_SUFFIX; outputStream = new FileOutputStream(new File(cpFilePath)); StreamUtils.copy(inputStream, outputStream); // 記錄檔案資訊 fileJson.put("name",reportName); fileJson.put("path",cpFilePath); } } catch (UnsupportedEncodingException e) { logger.error("設定post請求引數出錯!", e); } catch (ClientProtocolException e) { logger.error("連線失敗!", e); } catch (FileNotFoundException e) { logger.error("目標檔案未找到!", e); } catch (IOException e) { logger.error("獲取檔案流失敗!", e); } finally { try { if(outputStream != null) { outputStream.close(); } if(inputStream != null) { inputStream.close(); } } catch (IOException e) { logger.error("關閉流失敗!", e); } httPostDownload.abort(); } return fileJson; }
請求之後的返回資訊到將封裝在entity中,要獲取響應資料
// 獲取httpentity
HttpEntity httpEntityDownload = httpResponse.getEntity();
// 從httpentity中獲取輸入流
inputStream = httpEntityDownload.getContent();
這樣就會獲取到一個json物件,每個json物件得到的是一個資源在應用A伺服器上的具體位置和名字,再進行二次加工即可。不過最後記得要關閉httpclient物件。
httpClient.close();
記錄一下~