httpclient封装获取响应实体_Httpclient 接口自动化

好久木写啦!!!好久木写啦!!!

心血来潮分享点小白的东西!!!

废话少说直接干货!!!

本文核心是将如何从数据驱动开始,以报告结尾的形式来实现“很多刚入行朋友们”所需要的接口自动化

类型:驱动:excel

核心jar:httpclient

编译:maven(跟本文所讲有点沾不着边)

自动化框架 :testng(这个支持并发所以实现了并发的方法)

报告:ztest(有在之前tester老大哥的开源报告上实现了修改)

总结关键字:httpclient+maven+testng+ztest+excel

maven pom配置:

org.apache.httpcomponents

httpclient

4.5.5

com.alibaba

fastjson

1.2.47

org.testng

testng

6.14.3

test

其实实现可以很简单,因为在实现的过程中加入了并发的支持所以实现起来就变成了下面这样子(写的很水不喜勿喷)

请求类具体实现方式:

httpclient配置类:这个配置类主要目的分为三类

①如何支持https请求

②如何支持线程池

③自定义请求重试的机制

https是安全的ssl请求,官方给出的要想支持https请求就必须绕过请求证书,至于如何绕过需要实现一个X509TrustManager的接口

private static SSLContext createIgnoreVerifySSL() {

SSLContext sc = null;

try {

sc = SSLContext.getInstance("SSLv3");

} catch (NoSuchAlgorithmException e) {

logger.error("算法异常", e);

}

// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法

X509TrustManager trustManager = new X509TrustManager() {

public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,

String paramString) throws CertificateException {

}

public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,

String paramString) throws CertificateException {

}

public java.security.cert.X509Certificate[] getAcceptedIssuers() {

return null;

}

};

try {

sc.init(null, new TrustManager[] { trustManager }, null);

} catch (KeyManagementException e) {

logger.error("密钥管理异常", e);

}

return sc;

}

这样子下来ssl的配置就有了,然后在httpclient里面实现线程池的方法里面配置这个就好了

这样子就得到了线程池的对象,然后再给线程池一顿配置,具体代码有注释解释

第三个请求自定义重试机制(也可使用默认的重试机制,不实现这个方法,去掉这个配置就好了setRetryHandler(myRetryHandler)),我偏不信邪我就喜欢重写一个

这样子下来我需要的一些配置就有了

public synchronized static CloseableHttpClient createClient() {

SSLContext sslcontext = createIgnoreVerifySSL();

// 验证http,https请求,使用默认的连接请求,如有自定义需要

// 请查看https://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/connmgmt.html#d5e449,官方自定义证书验证文档

Registry registry = RegistryBuilder. create()

.register("http", PlainConnectionSocketFactory.INSTANCE)

.register("https", new SSLConnectionSocketFactory(sslcontext)).build();

// 线程池设置

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);// registry

// 最大连接总数

cm.setMaxTotal(MAX_CONN);

// 默认路由最大连接数

cm.setDefaultMaxPerRoute(Max_PRE_ROUTE);

// 主机端口最大连接数

HttpHost localhost = new HttpHost("music.migu.cn", 8000);

cm.setMaxPerRoute(new HttpRoute(localhost), MAX_ROUTE);

// http请求重试处理机制,重写方法

HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {

if (executionCount >= 10) {

logger.error("重试次数超过5", new Throwable("重试次数超过5"));

return false;

}

if (exception instanceof InterruptedIOException) {

logger.error("中断IO异常", new Throwable("中断IO异常"));

return false;

}

if (exception instanceof UnknownHostException) {

new Throwable().getMessage();

logger.error("未知主机");

return false;

}

if (exception instanceof ConnectTimeoutException) {

logger.error("连接超时", new Throwable("连接超时"));

return false;

}

if (exception instanceof SSLException) {

logger.error("sll握手异常", new Throwable("sll握手异常"));

return false;

}

HttpClientContext clientContext = HttpClientContext.adapt(context);

HttpRequest request = clientContext.getRequest();

boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);

if (idempotent) {

logger.error("带有请求的实体自动重试", new Throwable());

return true;

}

return false;

}

};

// 创建自定义将请求重试机制添加进去;客户端分createDefault() 与 custom()

CloseableHttpClient httpclient = HttpClients.custom().setKeepAliveStrategy(getkeepAliveStrat())

.setConnectionManager(cm).setRetryHandler(myRetryHandler).build();

return httpclient;

}

配置有了之后怎么办呢,那当然是实现请求啊

这里需要给大家科普一下头,头分为请求头跟响应头(网上大佬们写的我觉得还不错),因为请求头能自定义还是说一下比较好

请求方的http报头结构:通用报头|请求报头|实体报头

响应方的http报头结构:通用报头|响应报头|实体报头

Accept代表发送端(客户端)希望接受的数据类型。

比如:Accept:text/xml; /是所有类型都接受

代表客户端希望接受的数据类型是xml类型

Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。

比如:Content-Type:text/html;

代表发送端发送的数据格式是html。

解释完了然后开始实现get,post请求;实现请求之前需要在写一个setCookie的方法

写完了cookie之后就就可以当个人了

public BasicHeader setCookie(String head) {

BasicHeader cookie = new BasicHeader("Cookie", head);

return cookie;

}

接下来是get方法

get方法里面有两点必须要说明的 一个是response响应头信息,一个是response响应实体

response响应头:getReponsemes(response) 这个类实现了解析响应头里面的各种信息里面包含了两种方法

response响应实体:getResponseEntity(getEntity)响应实体httpclien官网给了一个流解析的api,但是这个api在某些时候会有bug所以这个流的解析基础上面又加入了一个解析判断,都有注释有注释你们看的懂的

这两个方法我就不细说了,后面我会放上git链接看官们可以自取

public List get(String url, String head) throws Exception {

List resList = new ArrayList();

CloseableHttpClient httpclient = HttpClientMain.createClient();// 创建客户端

CloseableHttpResponse response = null;// 创建响应

String res = null;// 请求结果

String statu = null;

int status;// 状态码

HttpEntity getEntity = null;

HttpGet get = null;

HttpClientContext context = HttpClientContext.create();

BasicHeader cookie = setCookie(head);

get = new HttpGet(url);

// get.setRequestProperty("Content-Type",

// "application/x-www-form-urlencoded;charset=utf-8");

// get.setRequestProperty("accept", "*/*");

// get.setHeader("HTTP_CLIENT_IP", "192.168.10.100");

get.addHeader("user-agent",

"Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36");

get.addHeader("Content-Type", CONTENT_TYPE_FORM_URLENCODED);

get.addHeader("accept", "*/*");

get.setHeader(cookie);

if (httpclient != null) {

response = httpclient.execute(get, context);

if (response != null) {

status = response.getStatusLine().getStatusCode();

getEntity = response.getEntity();

statu = response.getStatusLine().toString();

res = getResponseEntity(getEntity);

resList.add(getReponsemes(response).toString());

resList.add(statu);

resList.add(res);

if (status != 200) {

throw new Exception(res);

}

}

}

closeAll(httpclient, response);

return resList;

}

post方法:post方法多了一个请求参数至于怎么

public List post(String url, Map params, String head) throws Exception {

List resList = new ArrayList();

CloseableHttpClient httpclient = null;// 创建客户端

CloseableHttpResponse response = null;// 创建响应

HttpEntity postEntity = null;// 请求结果

HttpPost httpPost = null;// 请求方法

int statusCode;// 状态码

String res = null;

String statu = null;

BasicHeader cookie = setCookie(head);

httpclient = createClient();

HttpClientContext context = HttpClientContext.create();

httpPost = new HttpPost(url);

httpPost = setPostParams(httpPost, params, context, httpclient);

httpPost.addHeader("user-agent",

"Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36");

httpPost.addHeader("Content-Type", CONTENT_TYPE_FORM_URLENCODED);

httpPost.addHeader("accept", "*/*");

httpPost.setHeader(cookie);

response = httpclient.execute(httpPost, HttpClientContext.create());

statusCode = response.getStatusLine().getStatusCode();

// getReponsemes(response);

if (response != null) {

statusCode = response.getStatusLine().getStatusCode();

postEntity = response.getEntity();

statu = response.getStatusLine().toString();

res = getResponseEntity(postEntity);

resList.add(getReponsemes(response).toString());

resList.add(statu);

resList.add(res);

if (statusCode != 200) {

throw new Exception(res);

}

}

return resList;

}

好了到这里基本的主要方法都有了,然后利用testng去实现这些请求了

如果你深入了解testng这些看起来就很简单了

一个数据驱动方法,一个test方法,一个ztest的监听就完事了

@Listeners({ ZTestReport.class })

public class TestTemplate extends TestBase {

private String excelPath = prop1.getProperty("ExcelPath");

private String sheetName = "api";

private List re = null;

@Test(dataProvider = "data", threadPoolSize = 1, timeOut = 0, invocationCount = 1)

public synchronized void getData(String num, String nicName, String httpType, String reMethond, String host,

String path, String head, String paramType, String param, String verisy) throws Exception {

// 获取当前线程id System.out.println(Thread.currentThread().getId());

SendRequest sr = new SendRequest(num, nicName, httpType, reMethond, host, path, head, paramType, param, verisy);

re = sr.request();

for(String entry:re){

Reporter.log(entry);

}

}

/**

* 数据驱动

*/

@DataProvider(name = "data", parallel = true)

public Object[][] dataProvider() throws IOException, Exception {

return ExcelDataParam.readExcelDataParam(excelPath, sheetName);

}

然后只用到了test标签至于为什么完全是为了并发,至于是不是并发效果各位看官们可以打印时间到毫秒来看看,也可以打印线程id,至于支持多少并发完全取决于你的机器支持多少线程这里不多讲,干活基本就这么多了

少了一个SendRequest

这个类主要是继承了配置文件(比如你想配置开发,测试,生产的主机可以卸载配置文件里面)

这个类主要就是根据驱动里面的参数来判断怎么去执行,各个参数为空该怎么执行,参数类型不同该怎么执行没有技术含量的

public class SendRequest extends TestBase {

private String num;// 编号

private String nicName;// 用例名称

private String httpType;// 请求协议类型

private String reMethond;// 请求方法

private String host;// 主机

private String path;// 路径

private String head;// 请求头

private String paramType;// 参数类型 json param

private String param;// 请求参数

private String verisy;// 验证点

public SendRequest(String num, String nicName, String httpType, String reMethond, String host, String path,

String head, String paramType, String param, String verisy) {

this.num = num;

this.nicName = nicName;

this.httpType = httpType;

this.reMethond = reMethond;

this.host = host;

this.path = path;

this.head = head;

this.paramType = paramType;

this.param = param;

this.verisy = verisy;

}

/**

* 根据驱动类型来选择调用方法与参数类型接口调用类

*/

public List request() throws Exception {

List re = null;

if (path == null) {

path = "/";

}

if (host == null) {

host = prop1.getProperty("Host");

}

HttpClientMain req = new HttpClientMain();

if (reMethond.equalsIgnoreCase("get")) {

re = req.get(httpType + "://" + host + path, head);

} else {

// 如果是json参数先把字符串转json,在把json转map

if (paramType.equalsIgnoreCase("json")) {

JSONObject json = JSONObject.parseObject(param);

re = req.post(httpType + "://" + host + path, JsonToMap.jsonToMap(json), head);

} else {

re = req.post(httpType + "://" + host + path, ParToMap.strToMap(param), head);

}

}

return re;

}

}

至于报告是怎么实现的:https://testerhome.com/topics/10802 请看一下这位大佬的,对了大佬的报告没有验证点,所以我加上了后面git上面的rereport就是加了验证点的报告,大佬好一手jqury 害的我百度半天才加上

有疑问的跟我一样的小白们留言就好看到就会回

如果想骂人的请看这里:我手痒想些,就是手痒啊啊啊啊啊啊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器控件开发之基本概念

利用ASP.NET 2.0技术,创建Web自定义服务器控件并不是一件轻松的事情。因为,这需要开发人员了解并能够灵活应用多种Web开发技术,例如,CSS样式表、客户端脚本语言、.NET开发语言、服务器控件开发技术,甚至是当前最火的AJ…

如何在Django模板中注入全局变量

我们在做一些网站项目的时候,可能会遇到需要把某个全局变量注入到所有页面的情况,比如我们做一个在线商城,那么可能需要将用户的资料:比如用户的账号、用户的姓名等注入到每个页面里面。但是如果用常规的方法,也就是在…

JavaScript 定时器

setInterval 每隔time时间后执行内部代码,后边改的time时间并不起作用 var time 2000; var obj setInterval(() > {}, time);//obj 返回的是一个数字,作为唯一标识time200; //不起作用clearInterval(obj) //清除计时器setInterval("console.…

Ubuntu18.04更换为国内源

Ubuntu18.04更换为国内源 1、打开Linux终端,执行下列命令,将源文件备份,以防万一。 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak2、选择下列任意一个源,将其复制 ​ 2.1 阿里源 deb http://mirrors.aliyun.com/…

如何关闭大疆gps_如何使用djisdkforwindows从mavic 2获取gps数据?

我使用windows sdk。我正在尝试使用以下方法获取gps数据:var flightControllerHandler _djiManagerInstance.ComponentManager.GetFlightControllerHandler(ProductIndex, ComponentIndex);flightControllerHandler.AircraftLocationChanged - QuadcopterOnAircraftLocationCh…

跨线程访问控件

【转帖】 我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题,下面我将详细的介绍。 首先来看传统方法: public partial class Form1 : Form { public Fo…

解析Nginx负载均衡

摘要:对于一个大型网站来说,负载均衡是永恒的话题。随着硬件技术的迅猛发展,越来越多的负载均衡硬件设备涌现出来,如F5 BIG-IP、Citrix NetScaler、Radware等等,虽然可以解决问题,但其高昂的价格却往往令人…

基于vue+mint-ui的mobile-h5的项目说明

基于vuemint-ui的mobile-h5的项目说明转载于:https://www.cnblogs.com/ysx215/p/10768656.html

Ubuntu20.04更换为国内源

Ubuntu20.04更换为国内源 1、打开Linux终端,执行下列命令,将源文件备份,以防万一。 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak2、选择下列任意一个源,将其复制 ​ 2.1 阿里源 deb http://mirrors.aliyun.com/…

深圳办理cdn经营许可证_深圳危化品经营许可证申请流程怎么申请?办理危化学品经营许可证...

随着深圳地区慢慢的进入了产业整合和城市规划规范化的运营中,很多涉及到生产的公司都逐渐被有效的整合在一起了,而随着深圳地区越发有效的整合生产规划,很多地区都逐渐的在将涉及到危险化学品生产和经营的企业都进行合理的管制,在…

Discuz!NT 缓存设计简析 [原创]

作为一个社区类型软件,大并发支持和高效稳定运行永远是“硬道理”,而有效安全的使用缓存恰恰能起到事倍功半的效果。而.NET本身所提供的缓存机制又显得过于“单薄”,比如说订制不太灵活方便, 缓存对象之间层次感不强, 使用时缺乏统一的管理等…

实验七:Xen环境下cirrOS的安装配置

实验名称: Xen环境下cirrOS的安装配置 实验环境: 这里的cirrOS和实验六中的busybox的启动方式相同,唯一的区别就是我们使用的cirrOS镜像中,已经包含了根文件系统、内核文件以及ramdisk和grub程序; 只需要我们使用xen环…

携程SQL面试题忘大牛解答解决思路

讨论地址:http://bbs.csdn.net/topics/380208742

VSCode从下载到配置Ubuntu系统

Visual Studio Code从下载到配置Ubuntu系统 一、下载和安装Visual Studio Code 1、进入Visual Studio Code官网(Visual Studio Code - Code Editing. Redefined),点击箭头所指地方下载红框内的安装包; 2、因为是国外网址下载&am…

python 写入excel 日期_Python实例:excel文档写入操作

来自PythonABC.org老师的课程很好,但是每个视频都蛮长的,听着听着就有些晕乎,所以根据视频自己整理了一下,以便记录学习使用Python实现excel的文档写操作import openpyxl from openpyxl.utils import get_column_letterwb openpy…

Windows软件调试学习笔记(1)

——WINDBG中的表达式 WINDBG接受两种表达式,C表达式和MASM表达式。 1、 MASM表达式中的数值: MASM表达式中的数值可以基于16,10,8,2四种进制。用n命令可以设置WINDBG的缺省进制,如果没有设置过则默认为16。…

eclipse集成maven插件

一、准备工作 1. 安装jdk并配置:https://www.cnblogs.com/diandiangui/p/10002100.html  2. 已安装好 maven并配置:https://www.cnblogs.com/diandiangui/p/10768339.html  3. 安装eclipse并配置:https://www.cnblogs.com/diandiangui/p/…

VMware ESX与VMware ESXi区别

VMware ESX与VMware ESXi区别 2011-04-05 10:24:06| 分类: 虚拟机 | 标签: |字号大中小 订阅 VMware ESX 与 VMware ESXi 区别 前几天去一家公司看到一本书介绍VMWare ESXi ,就随手翻了翻,之前我在公司也架设过VMWare ESXi 4.0…

批量改名_手把手教你用Python批量给图片添加水印 | 知了干货分享

我们在网上浏览一些文章的时候,经常会发现文章中会有一些图片,上面会有一些标识,而这些标识就是我们经常说的水印了。很多时候,我们需要给图片加上一些修饰,好让别人能直观的认识到这个图片的出处以及来源,…

linux环境下安装nginx步骤(不错)

开始前,请确认gcc g开发类库是否装好,默认已经安装。 ububtu平台编译环境可以使用以下指令 apt-get install build-essential apt-get install libtool centos平台编译环境使用如下指令 安装make: yum -y install gcc automake autoconf libt…