转自: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; /** * 请求信息封装类 */@Datapublic 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); ???}httpclient获取响应实体和信息的封装方法(解耦更新)
原文地址:https://www.cnblogs.com/yadongliang/p/9665536.html