httpclient獲取響應實體和信息的封裝方法(解耦更新)


轉自:https://blog.csdn.net/fhaohaizi/article/details/77850302

2018年07月19日更新,主要是解耦之后方法很多地方發生了變化,httpclient用了連接池方式,作為一個靜態變量處理,請求頭和響應頭以及cookies設置都有了相關處理方法,本來這個方法已經快超過100行了,解耦之后分成了幾個小方法,方便修改和調試。分兩部分,一部分是框架,只做了公共處理,另外一部分是每個項目的base類需要重新實現一些這個方法來處理header信息以及需要特殊處理的地方。分享代碼如下:

/**
     * 獲取響應實體
     *
     * @param request 請求對象
     * @return 返回json類型的對象
     */
    protected static JSONObject getHttpResponse(HttpRequestBase request) {
        beforeRequest(request);
        JSONObject jsonObject = new JSONObject();
        RequestInfo requestInfo = new RequestInfo(request);
        CloseableHttpResponse response = null;// 創建響應對象
        Date start = getDate();// 記錄開始時間
        try {
            response = ClientManage.httpsClient.execute(request);
        } catch (Exception e) {
            new Thread(() -> new AlertOver("接口請求失敗", requestInfo.toString() + Arrays.toString(e.getStackTrace()), requestInfo.getUrl()).sendSystemMessage()).start();
            return jsonObject;
        }
        Date end = getDate();// 記錄結束時間
        double elapsed_time = getTimeDiffer(start, end);// 獲取響應耗時
        afterResponse(response);
        int status = response.getStatusLine().getStatusCode();// 獲取響應狀態
        String content = getContent(response);
        long data_size = content.length();
        jsonObject = getResponse(content);
        int code = checkCode(jsonObject, requestInfo.getUrl());
        if (status != HttpStatus.SC_OK)
            new Thread(() -> new AlertOver("響應狀態碼錯誤", "狀態碼錯誤:" + status, requestInfo.getUrl()).sendSystemMessage());
        MySqlTest.saveApiTestDate(requestInfo, data_size, elapsed_time, status, getMark(), code, LOCAL_IP, COMPUTER_USER_NAME);
        return jsonObject;
    }

下面是里面封裝方法的依次分享:

/**
     * 發送請求之前,配置請求管理器,設置IP,user_agent和cookie
     *
     * @param request
     */
    private static void beforeRequest(HttpRequestBase request) {
        request.setConfig(requestConfig);//設置請求配置
        request.addHeader(getHeader("X-FORWARDED-FOR", getRandomIP()));//隨機生成ip
        request.addHeader(HTTP.USER_AGENT, USER_AGENT);
        if (cookies != null && !Arrays.toString(request.getAllHeaders()).contains(REQUEST_HEADER_COOKIE))
            request.addHeader(REQUEST_HEADER_COOKIE, cookies);// 添加cookie
    }

requestinfo類的方法:

package com.fission.source.httpclient;
 
import com.fission.source.source.SourceCode;
import lombok.Data;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.util.EntityUtils;
 
import java.io.IOException;
 
/**
 * 請求信息封裝類
 */
@Data
public class RequestInfo extends SourceCode {
    /**
     * 接口地址
     */
    String apiName;
    /**
     * 請求的url
     */
    String url;
    /**
     * 請求的uri
     */
    String uri;
    /**
     * 方法,get/post
     */
    String method;
    /**
     * 域名
     */
    String host;
    /**
     * 協議類型
     */
    String type;
    /**
     * 參數
     */
    String params;
 
    /**
     * 通過request獲取請求的相關信息,並輸出部分信息
     *
     * @param request
     */
    public RequestInfo(HttpRequestBase request) {
        getRequestInfo(request);
        if (!host.contains("alertover") && !host.contains("lonelymind"))
            output(TAB + TAB + TAB + "請求uri:" + uri + LINE + TAB + TAB + TAB + "請求參數是:" + params);
    }
 
    /**
     * 封裝獲取請求的各種信息的方法
     *
     * @param request 傳入請求對象
     * @return 返回一個map,包含api_name,host_name,type,method,params
     */
    private void getRequestInfo(HttpRequestBase request) {
        method = request.getMethod();// 獲取method
        uri = request.getURI().toString();// 獲取uri
        getRequestUrl(uri);
        String one = url.substring(url.indexOf("//") + 2);// 刪除掉http://
        apiName = one.substring(one.indexOf("/"));// 獲取接口名
        host = one.substring(0, one.indexOf("/"));// 獲取host地址
        type = url.substring(0, url.indexOf("//") - 1);// 獲取協議類型
        if (method.equals(REQUEST_TYPE_GET)) {
            params = uri.substring(uri.indexOf("?") + 1, uri.length());
        } else if (method.equals(REQUEST_TYPE_POST)) {
            getPostRequestParams(request);
        }
    }
 
    /**
     * 獲取請求url,遇到get請求,先截取
     *
     * @param uri
     */
    private void getRequestUrl(String uri) {
        url = uri;
        if (uri.contains("?")) url = uri.substring(0, uri.indexOf("?"));
    }
 
    /**
     * 獲取post請求的參數
     *
     * @param request
     */
    private void getPostRequestParams(HttpRequestBase request) {
        HttpPost httpPost = (HttpPost) request;// 強轉httppost請求
        HttpEntity entity = httpPost.getEntity();// 獲取實體
        if (entity == null) return;
        try {
            params = EntityUtils.toString(entity);// 解析實體
            EntityUtils.consume(entity);// 確保實體消耗
        } catch (UnsupportedOperationException e) {
            params = "entity類型:" + entity.getClass();
        } catch (ParseException e) {
            output("解析響應實體異常!", e);
        } catch (IOException e) {
            output("解析響應實體時java IO 異常!", e);
        }
    }
}
/**
     * 響應結束之后,處理響應頭信息,如set-cookien內容
     *
     * @param response
     */
    private static void afterResponse(CloseableHttpResponse response) {
        if (response == null) return;
        List<Header> headers = Arrays.asList(response.getHeaders("Set-Cookie"));
        if (!headers.equals(new ArrayList<>())) setCookies(headers);
        if (cookieSet == false && cookies != null)
            cookieSet = true;
    }
/**
     * 根據響應獲取響應實體
     *
     * @param response
     * @return
     */
    private static String getContent(CloseableHttpResponse response) {
        HttpEntity entity = response.getEntity();// 獲取響應實體
        String content = EMPTY;
        try {
            content = EntityUtils.toString(entity, UTF_8);// 用string接收響應實體
            EntityUtils.consume(entity);// 消耗響應實體,並關閉相關資源占用
            if (response != null) response.close();
        } catch (ParseException e1) {
            output("解析響應實體異常!", e1);
        } catch (IOException e1) {
            output("解析響應實體時java IO 異常!", e1);
        }
        return content;
    }
    /**
     * 根據解析好的content,轉化json對象
     *
     * @param content
     * @return
     */
    private static JSONObject getResponse(String content) {
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject = JSONObject.fromObject(content);
        } catch (Exception e) {
            jsonObject.put("content", content);
            jsonObject.put("code", TEST_ERROR_CODE);
        }
        return jsonObject;
    }
    /**
     * 獲取並檢查code
     *
     * @param jsonObject
     * @param url
     * @return
     */
    private static int checkCode(JSONObject jsonObject, String url) {
        int code = TEST_ERROR_CODE;
        try {
            code = jsonObject.getInt("code");
            if (ERROR_CODE_LIST.contains(code))
                new Thread(() -> new AlertOver("responseCode錯誤", jsonObject.toString(), url).sendSystemMessage());
        } catch (Exception e) {
            output("響應非標准響應體!", e);
        }
        return code;
    }

其中數據庫存儲的和發送提醒消息的這里就不說了,數據庫一部存儲還在優化,alertover使用方法在其他文章分享過了。

------------------------------------分割線--------------------------------------

本人在使用httpclient做接口測試的時候,需要統計一下接口的一些信息,在寫用例的過程中為了提高復用,簡化一些結構,所以封裝了一些基本方法,分享一下獲取響應實體和響應信息的方法,共大家參考。

//獲取post響應,暫無header設置
    public JSONObject getHttpResponseEntityByJson(CloseableHttpClient httpClient, HttpPost httpPost) throws ClientProtocolException, IOException, SQLException, JSONException {
        //在請求中明確定義不要進行壓縮  
//        httpPost.setHeader("Accept-Encoding", "identity"); 
        HttpResponse response = null;//創建響應對象
        long date_size = 0;//用於存放數據大小
        String api_name = getApiName(httpPost);//獲取接口名稱
        String type = getProtocolType(httpPost);//獲取協議類型
        String host_name = getHostName(httpPost);//獲取hsot主機名稱
        Date start = getDate();//記錄開始時間
        response = httpClient.execute(httpPost);//獲取響應
        Date end = getDate();//記錄結束時間
        double elapsed_time= outputTimeDiffer(start, end, "接口:" + api_name);//獲取響應耗時
        int status = response.getStatusLine().getStatusCode();//獲取響應狀態
        if (status == HttpStatus.SC_OK) {//判斷一下返回狀態
            output("host:" + host_name, "接口:"+ api_name + "請求成功!");
            } else {
                output(response.getStatusLine().getStatusCode() + LINE + "請求失敗!");
            }
        HttpEntity entity = response.getEntity();//獲取響應實體
        data_size = entity.getContentLength();//獲取相應數據大小
        if (data_size == -1) {//如果為-1,則重置date_size
            date_size = 0;
        }
        String content = EntityUtils.toString(entity);//解析響應
        if (date_size == 0) {//如果被重置或者沒有獲取到,則date_size等於解析string大小
            date_size = content.length();
        }
        JSONObject jsonObject = new JSONObject(content);//轉換json
        LocalMySql.getInstance().saveApiTestDate(host_name, api_name, date_size, elapsed_time, status, type);
//        httpClient.close();//關閉客戶端
        return jsonObject;
    }
    //獲取get接口響應,暫無header設置
    public JSONObject getHttpResponseEntityByJson(CloseableHttpClient httpClient, HttpGet httpGet) throws ClientProtocolException, IOException, JSONException, SQLException {
        //在請求中明確定義不要進行壓縮
//        httpGet.setHeader("Accept-Encoding", "identity"); 
        HttpResponse response = null;
        long date_size = 0;
        String api_name = getApiName(httpGet);
        String type = getProtocolType(httpGet);
        Date start = getDate();
        response = httpClient.execute(httpGet);
        Date end = getDate();
        double elapsed_time= outputTimeDiffer(start, end, "接口:" + api_name);
        String host_name = getHostName(httpGet);
        int status = response.getStatusLine().getStatusCode();
        if (status == HttpStatus.SC_OK) {//判斷一下返回狀態
            output("host:" + host_name, "接口:"+ api_name + "請求成功!");
            } else {
                output(response.getStatusLine().getStatusCode() + LINE + "請求失敗!");
            }
        HttpEntity entity = response.getEntity();
        data_size = entity.getContentLength();
        if (data_size == -1) {
            date_size = 0;
        }
        String content = EntityUtils.toString(entity);
        if (date_size == 0) {
            date_size = content.length();
        }
        JSONObject jsonObject = new JSONObject(content);
        LocalMySql.getInstance().saveApiTestDate(host_name, api_name, date_size, elapsed_time, status, type);
//        httpClient.close();
        return jsonObject;
    }

中間使用了本地數據庫,將收集的信息存入本地數據庫里面,以便以后統計。代碼如下:

    //保存接口測試數據的方法
    public void saveApiTestDate(String host_name, String api_name, long date_size, double elapsed_time, int status, String type) throws SQLException {
        getConnection();
        if (!connection.isClosed()) {
            outputSuccess();
            Statement statement = connection.createStatement();
            String sql = "INSERT INTO api_result (host_name,api_name,date_size,elapsed_time,status,type) VALUES ('"+host_name+"','"+api_name+"',"
            +date_size+","+ elapsed_time + "," + status + ",'" + type +"');";
//            output(sql);
            statement.executeUpdate(sql);
        }
    }

中間用到了一些自己封裝的方法:

    //獲取json數據中的相應值
    public String getJsonValue(String jsonString, String key) throws JSONException {
        String JsonValue = null;
        if (jsonString == null || jsonString.trim().length() < 1) {//排除為空和空格
            return null;
            }
        JSONObject obj1 = new JSONObject(jsonString);
        JsonValue = (String) obj1.getString(key);
        return JsonValue;//返回對應值
    }
    //獲取json數據中的相應值
    public String getJsonValue(JSONObject jsonObject, String key)    {
        String JsonValue = "··-·";
        try {
            JsonValue = (String) jsonObject.getString(key);
        } catch (JSONException e) {
            output("json數據錯誤!");
            output(e.toString());
        }
        return JsonValue;//返回對應值
    }
    //把json數據轉化為參數
    public String changeJsonToArguments(JSONObject argument) {
        String one = argument.toString();
           String two ="?" + one.substring(1, one.length()-1).replace(",", "&").replace(":", "=").replace("\"", "");
           return two;
           }
    //獲取接口名稱
    public String getApiName(HttpGet httpGet) {
        String url = getUrl(httpGet);
        String apiName = url.substring(url.indexOf("m/") + 1);
        return apiName;
    }
    //獲取接口名稱
    public String getApiName(HttpPost httpPost) {
        String url = getUrl(httpPost);
        String apiName = url.substring(url.indexOf("m/") + 1);
        return apiName;
    }
    //獲取host名稱
    public String getHostName(HttpPost httpPost) {
        String url = getUrl(httpPost);
        String host = url.substring(url.indexOf("//") + 2, url.indexOf("m/") + 2);
        return host;
    }
    //獲取host名稱
    public String getHostName(HttpGet httpGet) {
        String url = getUrl(httpGet);
        String host = url.substring(url.indexOf("//") + 2, url.indexOf("m/") + 2);
        return host;
    }
    //獲取url
    public String getUrl(HttpGet httpGet) {
        String uri = httpGet.getURI().toString();
        String url = uri.substring(0, uri.indexOf("?"));
        return url;
    }
    //獲取url
    public String getUrl(HttpPost httpPost) {
        String url = httpPost.getURI().toString();
        if (url.contains("?")) {
            url = url.substring(0, url.indexOf("?"));
        }
        return url;
    }
    //獲取協議類型
    public String getProtocolType(HttpGet httpGet) {
        String uri = httpGet.getURI().toString();
        String type = uri.substring(0, uri.indexOf("//") - 1);
        return type;
    }
    //獲取協議類型
    public String getProtocolType(HttpPost httpPost) {
        String uri = httpPost.getURI().toString();
        String type = uri.substring(0, uri.indexOf("//") - 1);
        return type;
    }
    //輸出json
    public void output(JSONObject jsonObject) {
        String info = jsonObject.toString().replaceAll(",", LINE);
        output(info);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM