前面写了一个HTTP的请求demo,使用的是GET请求方式,然而实际应用中,我们可能遇到POST、PUT或DELETE等,那么我们就还得实现其他请求方式的方法,并对其做一个封装,方便后续调用,在这里我准备将GET和POST请求方法都封装在HttpRequest类中,并会详细的介绍GET方法的封装思路,POST就直接贴代码了
一、封装GET方法
GET请求方式通常只需要有url(path+参数)就行,对于某些接口可能还需要设置header,所以在方法中我们都要支持这些设置了。下面我就用apache下的HttpClient来封装HTTP的GET请求封装(当然你也可以用java.net相关类实现,只不过HttpClient已经做了封装,使用起来更加方便)。
1、导入HttpClient相关jar包
这里我继续使用maven方式,IDE新建maven项目这个步骤就省略了,这一步在前一篇入门的文章有简单介绍。这里使用的是市面上使用率较大的HttpClient 4.3.5版本。
org.apache.httpcomponents
httpclient
4.3.5
org.apache.httpcomponents
httpmime
4.3.5
2、封装实现
a. 设置url
不管是GET还是POST等其他方式,都是需要设置请求url的,那么url对于HttpRequest类就是一个必填参数了,那么就可以将它设置在构造方法中。
private String url;
public HttpRequest(String url){
this.url = url;
}
b. 设置header,可选
请求头信息中除了设置请求的类型,字符编码,还可以设置用户信息,cookies等等,由于整个请求设置我想按链式(如:new HttpRequest(url).setHeaders(headers).setParams(params).doGet())设置,所以让setHeaders返回了HttpRequest对象类型,header通常也是按key-value形式表现的,所以传入的是Map类型的参数。
private Map headers;
public HttpRequest setHeaders(Map headers){
this.headers = headers;
return this;
}
c. 设置请求参数,可选
GET请求的参数可以放在url的?后面按key1=value1&key2=value2方式表现,所以这里我特别说明了是可选,如果参数特别多或比较长我们没有在url后面设置,也可以通过setParams方法来设置,setParams方法的返回类型和参数类型设置为HttpRequest和Map的设计原因跟setHeaders一样。
private Map params;
public HttpRequest setParams(Map params;){
this.params = params;
return this;
}
d. 请求方法doGet()
最后在doGet方法中将上述设置整合传入再发起请求。
public HttpResponse doGet(){
try {
HttpClient client = new DefaultHttpClient();
//设置参数,自带的request.setParams已弃用,所以自己拼接参数吧
if(params != null && params.size() > 0){
StringBuilder sb = new StringBuilder();
if(! url.contains("?")){
sb.append("?");
}
for(Map.Entry param : params.entrySet()) {
sb.append(param.getKey() + "=" + param.getValue() + "&");
}
sb.deleteCharAt(sb.lastIndexOf("&"));
url = url + sb.toString();
}
//发送get请求
HttpGet request = new HttpGet(url);
//设置headers
if(headers != null && headers.size() > 0){
for(Map.Entry header : headers.entrySet()) {
request.setHeader(header.getKey(), String.valueOf(header.getValue()));
}
}
//响应结果
HttpResponse response = client.execute(request);
return response;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
ok,这样GET请求就封装好了,上面的设计和实现思路我觉得是已经很详细了,如果有觉得不理解的地方可以留言哈。
二、封装POST方法
POST方法的封装跟GET思路是一样的,只是POST方法在参数设置上会有点差别,另外还可能会多了一个设置body内容content,其他都一样,下面我就直接贴出代码了,不再详细讲解POST的封装思路了。
private String content;
public HttpRequest setContent(String content){
this.content = content;
return this;
}
public HttpResponse doPost(){
try {
HttpClient client = new DefaultHttpClient();
//发送get请求
HttpPost request = new HttpPost(url);
//设置url
request.setURI(new URI(url));
if(headers != null && headers.size() > 0){
for(Map.Entry header : headers.entrySet()) {
request.setHeader(header.getKey(), String.valueOf(header.getValue()));
}
}
List nvps = new ArrayList();
//设置参数
if(params != null && params.size() > 0){
for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String value = String.valueOf(params.get(name));
nvps.add(new BasicNameValuePair(name, value));
}
request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
}
//设置body内容
if(content != null){
request.setEntity(new StringEntity(content));
}
HttpResponse response = client.execute(request);
return response;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
POST方法也封装好了,为了验证框架封装的是否可行,下面我们得跑个测试用例测试下。
a. 测试doGet()方法
@Test
public void testGet() throws ParseException, IOException{
String url = "http://api.fixer.io/latest?base=CNY";
//链式调用
HttpResponse response = new HttpRequest(url)
.setHeaders(null)
.setParams(null)
.doGet();
//输出响应
System.out.println(EntityUtils.toString(response.getEntity()));
//验证响应码
int code = response.getStatusLine().getStatusCode();
Assert.assertEquals(200, code);
}
测试结果:
b. 测试doPost()方法
测试doPost我自己写了一个API,就以这个API来做试验。
@Test
public void testPost() throws ParseException, IOException{
String url = "http://localhost:8090/api/add";
//header
Map header = new HashMap();
header.put("Content-Type","application/json");
HttpResponse response = new HttpRequest(url)
.setHeaders(header)
.setContent("{\"id\":12,\"data\":\"restful api test\",\"version\":\"v2\",\"date\":\"20171217\"}")
.doPost();
//输出响应
System.out.println(EntityUtils.toString(response.getEntity()));
//验证响应码
int code = response.getStatusLine().getStatusCode();
Assert.assertEquals(200, code);
}
测试结果:
注:虽然上面doGet和doPost方法的测试也都通过了,但是并不能保证所有类型的接口都能请求成功,这是为啥?因为上面处理的都是HTTP的,那么HTTPS支持吗?又挖个坑放这里。。。。。。
总结
本次分享就到这里了,着重分享封装的思路,可能有些朋友已经注意到这次的代码没有完整的全部贴出来,一来是想让大家可以动手思考,二来是想提高下公众号的关注度,希望大家多多点赞、转发(不然这么冷的天哪有动力敲键盘不是么_),获取源码可以在公众号中回复:“http封装”即可拿到源码。
【下章节预告】:接口自动化测试(六):数据验证专项
原文来自下方公众号,转载请联系作者,并务必保留出处。
想第一时间看到更多原创技术好文和资料,请关注公众号:测试开发栈