目前接口测试使用jmeter工具配置服务器IP、端口号、协议、url路径、请求方法、请求参数,参考jmeter的设计我们可以用编程语言自己实现一个客户端,本文主要讲一下使用httpclient构造http/https客户端的代码实现。
1.公共请求参数类,主要包括IP、端口号、协议、所有请求组成的链表
import java.util.List;
/**
* ClassName: RequestParameter
*
* @author xiezhaoqing192
* @date 2016年4月26日
*/
public class RequestParameter {
private String host;
private int port;
private String protocol;
private List<BasicParameter> basparams;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public List<BasicParameter> getBasparams() {
return basparams;
}
public void setBasparams(List<BasicParameter> basparams) {
this.basparams = basparams;
}
}
2.具体的请求参数类
import java.util.HashMap;
import java.util.Map;
/**
* ClassName: BasicParameter
*
* @author xiezhaoqing192
* @date 2016年4月26日
*/
public class BasicParameter {
private String apiUrl;
private String method;
private Map<String,String> paramters=new HashMap<String,String>();
private String uniqueid;
private Map<String,String> fileList=new HashMap<String,String>();
//新增逻辑,支持后置处理器 2016.05.20 by djj
private Map<String,String> afterCatch=new HashMap<String,String>();
/**
* 默认构造函数
* @param String apiUrl,String method,String uniqueid
* @return N/A
* @throws N/A
*/
public BasicParameter(String apiUrl,String method,String uniqueid){
this.apiUrl=apiUrl;
this.method=method;
this.uniqueid=uniqueid;
}
public String getApiUrl() {
return apiUrl;
}
public void setApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public Map<String,String> getParamters() {
return paramters;
}
public void addParamters(String key,String value) {
paramters.put(key, value);
}
public void addFile(String key,String value) {
fileList.put(key, value);
}
public void addAfterCatch(String key,String value) {
afterCatch.put(key, value);
}
public String getUniqueid() {
return uniqueid;
}
public void setUniqueid(String uniqueid) {
this.uniqueid = uniqueid;
}
public Map<String,String> getAfterCatch() {
return afterCatch;
}
/**
* @return the fileList
*/
public Map<String,String> getFileList() {
return fileList;
}
/**
* @param fileList the fileList to set
*/
public void setFileList(Map<String,String> fileList) {
this.fileList = fileList;
}
}
3.响应参数类
import java.util.HashMap;
import java.util.Map;
import org.apache.http.Header;
/**
* ClassName: BasicResponse
*
* @author xiezhaoqing192
* @date 2016年4月26日
*/
public class ResponseParameter {
private int respcode;
private String respdata;
private String respmsg;
private String uniqueid;
private int runtime;
private String urlString;
private Map<String,String>headers=new HashMap<String,String>();
public Integer getRespcode() {
return respcode;
}
public void setRespcode(Integer respcode) {
this.respcode = respcode;
}
public String getRespmsg() {
return respmsg;
}
public void setRespmsg(String respmsg) {
this.respmsg = respmsg;
}
public String getUniqueid() {
return uniqueid;
}
public void setUniqueid(String uniqueid) {
this.uniqueid = uniqueid;
}
public Integer getRuntime() {
return runtime;
}
public void setRuntime(Integer runtime) {
this.runtime = runtime;
}
/**
* @return the headers
*/
public Map<String,String> getHeaders() {
return headers;
}
/**
* @param headers the headers to set
*/
public void setHeaders(Header[] headers) {
if(headers!=null)
for(Header header:headers)
{
this.headers.put(header.getName(), header.getValue());
}
}
/**
* @return the urlString
*/
public String getUrlString() {
return urlString;
}
/**
* @param urlString the urlString to set
*/
public void setUrlString(String urlString) {
this.urlString = urlString;
}
/**
* @return the respdata
*/
public String getRespdata() {
return respdata;
}
/**
* @param respdata the respdata to set
*/
public void setRespdata(String respdata) {
this.respdata = respdata;
}
}
4.创建URI
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;
/**
* ClassName: HttpURIBuilder
*
* @author xiezhaoqing192
* @date 2016年4月26日
*/
public class HttpURIBuilder {
public static URI buildHttpURI(String host, int port, String api,
List<NameValuePair> nvps,String protocol) {
URI uri = URI.create("");
try {
URIBuilder builder = new URIBuilder();
builder.setScheme(protocol);
builder.setHost(host);
builder.setPort(port);
builder.setPath(api);
if(null != nvps)
for (NameValuePair nvp:nvps){
builder.setParameter(nvp.getName(), nvp.getValue());
}
uri = builder.build();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return uri;
}
}
5.HttpClient具体实现类
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.entity.mime.content.FileBody;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
/**
* ClassName: HttpResImpl
* @warming 这个类为核心类,封装了基本请求,后置处理器,类正则提取,请勿更改任何逻辑
2016.05.20 at丁晶晶
* @author xiezhaoqing192
* @date 2016年4月26日
*/
@SuppressWarnings("deprecation")
public class HttpResImpl implements HttpRes{
private Logger logger = LoggerFactory.getLogger(HttpResImpl.class);
private HttpClient httpclient = null;
private HttpResponse response = null;
private Map<String,String> afterCatchPool=new HashMap<String,String>();
@Override
public HttpResponse getInstance() {
if (null == response) {
response = new BasicHttpResponse(new ProtocolVersion("HTTP_ERROR", 1, 1), 500, "ERROR");
}
return response;
}
@Override
public HttpClient createHttpClient(String protocol) {
HttpParams params = new BasicHttpParams();
// 连接超时
HttpConnectionParams.setConnectionTimeout(params, HttpConstants.TIMEOUT);
// 请求超时
HttpConnectionParams.setSoTimeout(params, HttpConstants.TIMEOUT);
//保持长连接设置,后期将这个引出吧
// HttpConnectionParams.setSoKeepalive(params, false);
// 设置我们的HttpClient支持HTTP和HTTPS两种模式
SchemeRegistry schReg = new SchemeRegistry();
if ("HTTP".equals(protocol.toUpperCase())) {
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
} else if ("HTTPS".equals(protocol.toUpperCase())) {
// 创建TrustManager()
// 用于解决javax.net.ssl.SSLPeerUnverifiedException: peer not
// authenticated
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
// 创建HostnameVerifier
// 用于解决javax.net.ssl.SSLException: hostname in certificate didn't
// match: <202.69.27.140> != <*.pingan.com.cn>
X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
};
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance(SSLSocketFactory.TLS);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用
try {
sslContext.init(null, new TrustManager[] { trustManager }, null);
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 创建SSLSocketFactory
SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext, hostnameVerifier);
schReg.register(new Scheme("https", socketFactory, 443));
} else {
logger.error("不支持除http/https之外的协议");
}
// 使用线程安全的连接管理来创建HttpClient
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
if(httpclient==null){
httpclient = new DefaultHttpClient(conMgr, params);
}
return httpclient;
}
@Override
public List<ResponseParameter> execute(RequestParameter reqparams) {
httpclient = createHttpClient(reqparams.getProtocol());
response = getInstance();
List<ResponseParameter> resparams = new ArrayList<ResponseParameter>();
for (BasicParameter bp : reqparams.getBasparams()) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params = MapToNvps.convertToNvps(bp.getParamters(),afterCatchPool);
ResponseParameter rp = new ResponseParameter();
long startMili = 0;//定义开始时间
long endMili=0;//定义结束时间
URI request = HttpURIBuilder.buildHttpURI(reqparams.getHost(), reqparams.getPort(), bp.getApiUrl(), params,
reqparams.getProtocol());
String urlString=request.toString();
try {
if ("GET".equals(bp.getMethod().toUpperCase())) {
HttpGet hg = new HttpGet(request);
startMili=System.currentTimeMillis();// 当前时间对应的毫秒数
response = httpclient.execute(hg);
endMili=System.currentTimeMillis();// 当前时间对应的毫秒数-结束
}
else if ("POST".equals(bp.getMethod().toUpperCase())) {
HttpPost httppost = new HttpPost(request);
MultipartEntity entity = new MultipartEntity();
if(bp.getFileList()!=null)
for( Map.Entry<String, String> filePara:bp.getFileList().entrySet()){
try{
File file = new File(filePara.getValue());
FileBody fileBody = new FileBody(file);
entity.addPart(filePara.getKey(), fileBody);
}
catch(Exception e){
}
};
for(Map.Entry<String, String> para:bp.getParamters().entrySet()){
StringBody paraMeters = new StringBody(para.getValue());
entity.addPart(para.getKey(), paraMeters);
}
httppost.setEntity(entity);
startMili=System.currentTimeMillis();// 当前时间对应的毫秒数
response = httpclient.execute(httppost);
endMili=System.currentTimeMillis();// 当前时间对应的毫秒数-结束
}
else if ("PUT".equals(bp.getMethod().toUpperCase())) {
HttpPut p = new HttpPut(request);
startMili=System.currentTimeMillis();// 当前时间对应的毫秒数
response = httpclient.execute(p);
endMili=System.currentTimeMillis();// 当前时间对应的毫秒数-结束
}
else if ("DELETE".equals(bp.getMethod().toUpperCase())) {
HttpDelete hd = new HttpDelete(request);
startMili=System.currentTimeMillis();// 当前时间对应的毫秒数
response = httpclient.execute(hd);
endMili=System.currentTimeMillis();// 当前时间对应的毫秒数-结束
}
rp.setHeaders(response.getAllHeaders());
rp.setRespcode(response.getStatusLine().getStatusCode());
rp.setRespmsg(response.getStatusLine().getReasonPhrase());
rp.setUniqueid(bp.getUniqueid());
rp.setUrlString(urlString);
rp.setRuntime((int) (endMili-startMili));
try{
rp.setRespdata(EntityUtils.toString(response.getEntity(),"UTF-8"));}
catch(IOException e){
rp.setRespdata("自动化平台不支持的返回对象");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
endMili=System.currentTimeMillis();
e.printStackTrace();
rp.setHeaders(null);
rp.setRespcode(408);
rp.setRespdata(null);
rp.setRespmsg("找不到服务器:"+e.getMessage());
rp.setUniqueid(bp.getUniqueid());
rp.setRuntime((int) (endMili-startMili));
rp.setUrlString(urlString);
}
catch (ConnectTimeoutException e) {
// TODO Auto-generated catch block
endMili=System.currentTimeMillis();
e.printStackTrace();
rp.setHeaders(null);
rp.setRespcode(408);
rp.setRespdata(null);
rp.setRespmsg("连接超时:"+e.getMessage());
rp.setUniqueid(bp.getUniqueid());
rp.setRuntime((int) (endMili-startMili));
rp.setUrlString(urlString);
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
endMili=System.currentTimeMillis();
e.printStackTrace();
rp.setHeaders(null);
rp.setRespcode(408);
rp.setRespdata(null);
rp.setRespmsg(e.getMessage());
rp.setUniqueid(bp.getUniqueid());
rp.setRuntime((int) (endMili-startMili));
rp.setUrlString(urlString);
} catch (IOException e) {
// TODO Auto-generated catch block
endMili=System.currentTimeMillis();
e.printStackTrace();
rp.setHeaders(null);
rp.setRespcode(408);
rp.setRespdata(null);
rp.setRespmsg(e.getMessage());
rp.setUniqueid(bp.getUniqueid());
rp.setRuntime((int) (endMili-startMili));
rp.setUrlString(urlString);
}
catch (Exception e) {
endMili=System.currentTimeMillis();
e.printStackTrace();
rp.setHeaders(null);
rp.setRespcode(408);
rp.setRespdata(null);
rp.setRespmsg(e.getMessage());
rp.setUniqueid(bp.getUniqueid());
rp.setRuntime((int) (endMili-startMili));
rp.setUrlString(urlString);
}
resparams.add(rp);
String responseString;
//获取接口的json
Map<String,String>afterCatchMap= bp.getAfterCatch();//获取后置处理器
for(Map.Entry<String,String> afterCatch:afterCatchMap.entrySet()){
//这里异常不抛出去,如果这里出现错误,则直接给后置处理器赋空
try {
responseString = rp.getRespdata();//获取接口的json
String afterCatchValue=JsonHelper.getValueInJsonStringByKey(afterCatch.getValue(), responseString);//获取json提取值
afterCatchPool.put(afterCatch.getKey(), afterCatchValue);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
afterCatchPool.put(afterCatch.getKey(), null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
afterCatchPool.put(afterCatch.getKey(), null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
afterCatchPool.put(afterCatch.getKey(), null);
}
}
}
return resparams;
}
/**
* @return the afterCatchPool
*/
public Map<String,String> getAfterCatchPool() {
return afterCatchPool;
}
/**
* @param afterCatchPool the afterCatchPool to set
*/
public void setAfterCatchPool(Map<String,String> afterCatchPool) {
this.afterCatchPool = afterCatchPool;
}
}
以上就实现了支持http/https协议的client。