前面寫了一個HTTP的請求demo芦鳍,使用的是GET請求方式肩袍,然而實際應(yīng)用中,我們可能遇到POST博杖、PUT或DELETE等椿胯,那么我們就還得實現(xiàn)其他請求方式的方法,并對其做一個封裝剃根,方便后續(xù)調(diào)用哩盲,在這里我準(zhǔn)備將GET和POST請求方法都封裝在HttpRequest類中,并會詳細的介紹GET方法的封裝思路,POST就直接貼代碼了
一廉油、封裝GET方法
GET請求方式通常只需要有url(path+參數(shù))就行惠险,對于某些接口可能還需要設(shè)置header,所以在方法中我們都要支持這些設(shè)置了抒线。下面我就用apache下的HttpClient來封裝HTTP的GET請求封裝(當(dāng)然你也可以用java.net相關(guān)類實現(xiàn)班巩,只不過HttpClient已經(jīng)做了封裝,使用起來更加方便)十兢。
1趣竣、導(dǎo)入HttpClient相關(guān)jar包
這里我繼續(xù)使用maven方式,IDE新建maven項目這個步驟就省略了旱物,這一步在前一篇入門的文章有簡單介紹遥缕。這里使用的是市面上使用率較大的HttpClient 4.3.5版本。
<dependencies>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.5</version>
</dependency>
</dependencies>
2宵呛、封裝實現(xiàn)
a. 設(shè)置url
不管是GET還是POST等其他方式单匣,都是需要設(shè)置請求url的,那么url對于HttpRequest類就是一個必填參數(shù)了宝穗,那么就可以將它設(shè)置在構(gòu)造方法中户秤。
private String url;
public HttpRequest(String url){
this.url = url;
}
b. 設(shè)置header,可選
請求頭信息中除了設(shè)置請求的類型逮矛,字符編碼鸡号,還可以設(shè)置用戶信息,cookies等等须鼎,由于整個請求設(shè)置我想按鏈?zhǔn)剑ㄈ纾簄ew HttpRequest(url).setHeaders(headers).setParams(params).doGet())設(shè)置鲸伴,所以讓setHeaders返回了HttpRequest對象類型,header通常也是按key-value形式表現(xiàn)的晋控,所以傳入的是Map類型的參數(shù)汞窗。
private Map<String,Object> headers;
public HttpRequest setHeaders(Map<String,Object> headers){
this.headers = headers;
return this;
}
c. 設(shè)置請求參數(shù),可選
GET請求的參數(shù)可以放在url的?后面按key1=value1&key2=value2方式表現(xiàn)赡译,所以這里我特別說明了是可選仲吏,如果參數(shù)特別多或比較長我們沒有在url后面設(shè)置,也可以通過setParams方法來設(shè)置蝌焚,setParams方法的返回類型和參數(shù)類型設(shè)置為HttpRequest和Map的設(shè)計原因跟setHeaders一樣裹唆。
private Map<String,Object> params;
public HttpRequest setParams(Map<String,Object> params;){
this.params = params;
return this;
}
d. 請求方法doGet()
最后在doGet方法中將上述設(shè)置整合傳入再發(fā)起請求。
public HttpResponse doGet(){
try {
HttpClient client = new DefaultHttpClient();
//設(shè)置參數(shù)只洒,自帶的request.setParams已棄用品腹,所以自己拼接參數(shù)吧
if(params != null && params.size() > 0){
StringBuilder sb = new StringBuilder();
if(! url.contains("?")){
sb.append("?");
}
for(Map.Entry<String,Object> param : params.entrySet()) {
sb.append(param.getKey() + "=" + param.getValue() + "&");
}
sb.deleteCharAt(sb.lastIndexOf("&"));
url = url + sb.toString();
}
//發(fā)送get請求
HttpGet request = new HttpGet(url);
//設(shè)置headers
if(headers != null && headers.size() > 0){
for(Map.Entry<String,Object> header : headers.entrySet()) {
request.setHeader(header.getKey(), String.valueOf(header.getValue()));
}
}
//響應(yīng)結(jié)果
HttpResponse response = client.execute(request);
return response;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
ok,這樣GET請求就封裝好了红碑,上面的設(shè)計和實現(xiàn)思路我覺得是已經(jīng)很詳細了舞吭,如果有覺得不理解的地方可以留言哈泡垃。
二、封裝POST方法
POST方法的封裝跟GET思路是一樣的羡鸥,只是POST方法在參數(shù)設(shè)置上會有點差別蔑穴,另外還可能會多了一個設(shè)置body內(nèi)容content,其他都一樣惧浴,下面我就直接貼出代碼了存和,不再詳細講解POST的封裝思路了。
private String content;
public HttpRequest setContent(String content){
this.content = content;
return this;
}
public HttpResponse doPost(){
try {
HttpClient client = new DefaultHttpClient();
//發(fā)送get請求
HttpPost request = new HttpPost(url);
//設(shè)置url
request.setURI(new URI(url));
if(headers != null && headers.size() > 0){
for(Map.Entry<String,Object> header : headers.entrySet()) {
request.setHeader(header.getKey(), String.valueOf(header.getValue()));
}
}
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
//設(shè)置參數(shù)
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));
}
//設(shè)置body內(nèi)容
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";
//鏈?zhǔn)秸{(diào)用
HttpResponse response = new HttpRequest(url)
.setHeaders(null)
.setParams(null)
.doGet();
//輸出響應(yīng)
System.out.println(EntityUtils.toString(response.getEntity()));
//驗證響應(yīng)碼
int code = response.getStatusLine().getStatusCode();
Assert.assertEquals(200, code);
}
測試結(jié)果:
b. 測試doPost()方法
測試doPost我自己寫了一個API柿顶,就以這個API來做試驗茄袖。
@Test
public void testPost() throws ParseException, IOException{
String url = "http://localhost:8090/api/add";
//header
Map<String, Object> header = new HashMap<String, Object>();
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();
//輸出響應(yīng)
System.out.println(EntityUtils.toString(response.getEntity()));
//驗證響應(yīng)碼
int code = response.getStatusLine().getStatusCode();
Assert.assertEquals(200, code);
}
測試結(jié)果:
注:雖然上面doGet和doPost方法的測試也都通過了,但是并不能保證所有類型的接口都能請求成功嘁锯,這是為啥宪祥?因為上面處理的都是HTTP的,那么HTTPS支持嗎家乘?又挖個坑放這里蝗羊。。仁锯。耀找。。业崖。
總結(jié)
本次分享就到這里了野芒,著重分享封裝的思路,可能有些朋友已經(jīng)注意到這次的代碼沒有完整的全部貼出來腻要,一來是想讓大家可以動手思考复罐,二來是想提高下公眾號的關(guān)注度涝登,希望大家多多點贊雄家、轉(zhuǎn)發(fā)(不然這么冷的天哪有動力敲鍵盤不是么_),獲取源碼可以在公眾號中回復(fù):“http封裝”即可拿到源碼胀滚。
【下章節(jié)預(yù)告】:接口自動化測試(六):數(shù)據(jù)驗證專項
原文來自下方公眾號趟济,轉(zhuǎn)載請聯(lián)系作者,并務(wù)必保留出處咽笼。
想第一時間看到更多原創(chuàng)技術(shù)好文和資料顷编,請關(guān)注公眾號:測試開發(fā)棧