1. 程式人生 > >Java使用HttpClient模擬http(登入、請求資源並二次處理)栗子

Java使用HttpClient模擬http(登入、請求資源並二次處理)栗子

在工作中遇到過在一個伺服器應用(A)上去請求另一個伺服器應用(B)上的資源,然後在A中去二次處理該資源的問題,其實追根到底,就是一次cp的操作。

因為B應用是一個第三方的應用,只能通過使用http請求的方式去獲取其上的資源。

做個簡單的示意圖:

55b0f99c3bb1835051ee9e7169740d1fade.jpg

接下來上程式碼:

首先,模擬登陸記錄 :

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();

記錄一下~