HTML表單
許多應(yīng)用需要模仿一個(gè)登陸HTML表單的過(guò)程,比如:為了登陸一個(gè)WEB應(yīng)用或者提交輸入的數(shù)據(jù)裁蚁。Httpclient 早就為我們準(zhǔn)備好了患久,提供了UrlEncodedFormEntity類來(lái)簡(jiǎn)化操作屎勘。
我們來(lái)看一下核心的代碼:
List<NameValuePair> list = new ArrayList<>() ;
list.add(new BasicNameValuePair("name" ,"zhangsan"));
list.add(new BasicNameValuePair("age" ,"18"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list ,Consts.UTF_8) ;
post方法提交demo
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by YuLuo on 2016/12/5.
*/
public class PostDemo {
public static void main(String[] args) throws IOException {
demo();
}
public static void demo() throws IOException {
//創(chuàng)建httpclient 實(shí)例
CloseableHttpClient httpclient = HttpClients.createDefault();
//創(chuàng)建post方法實(shí)例
HttpPost post = new HttpPost("http://host/.com") ;
//封裝提交到服務(wù)器的參數(shù)信息
List<NameValuePair> list = new ArrayList<>() ;
list.add(new BasicNameValuePair("name" ,"zhangsan"));
list.add(new BasicNameValuePair("age" ,"18"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list , Consts.UTF_8) ;
//設(shè)置參數(shù)信息
post.setEntity(formEntity);
//提交post方法
CloseableHttpResponse respone = httpclient.execute(post);
int statcode = respone.getStatusLine().getStatusCode() ;
if(statcode == HttpStatus.SC_OK){
System.out.println(EntityUtils.toString(respone.getEntity()));
}
}
}
**解析NameValuePair **
通過(guò)查看源碼,發(fā)現(xiàn)NameValuePair只有兩個(gè)方法:
- getName()
- getValue()
BasicNameValuePair作為NameValuePair的實(shí)現(xiàn)類仲吏,只有兩個(gè)字段,Name和Value 蝌焚,并且它還實(shí)現(xiàn)了Cloneable 裹唆,Serializable 兩個(gè)接口。BasicNameValuePair 沒有提供屬性的setter方法综看。只能通過(guò)構(gòu)造方法品腹,為字段賦值。
內(nèi)容分塊
通過(guò)HTTP#setChunded()方法來(lái)通知HttpClient你要進(jìn)行分塊處理红碑, 由Httpclient根據(jù)被傳輸?shù)膱?bào)文屬性選擇最合適的傳輸編碼方式舞吭。當(dāng)使用一些不支持分塊的版本(http /1.0)時(shí),這個(gè)值會(huì)被忽略掉析珊。
Http執(zhí)行上下文 context
最初羡鸥,HTTP是被設(shè)計(jì)成無(wú)狀態(tài)的,面向請(qǐng)求-響應(yīng)協(xié)議忠寻。然而惧浴,我們?cè)谑褂玫倪^(guò)程中,經(jīng)常需要一些邏輯相關(guān)的請(qǐng)求-響應(yīng)交換來(lái)保持狀態(tài)信息奕剃。為了使應(yīng)用程序能夠維持一個(gè)過(guò)程狀態(tài)衷旅,httpclient允許HTTP請(qǐng)求在一個(gè)特定的執(zhí)行上下文中來(lái)執(zhí)行--稱為HTTP上下文。
HttpContext能夠包含任意的對(duì)象纵朋,因此在兩個(gè)不同的線程中共享上下文是不安全的柿顶。建議每個(gè)線程都有一個(gè)自己的上下文。
在HTTP請(qǐng)求執(zhí)行的過(guò)程中操软,HttpClient添加了下列屬性到執(zhí)行上下文中:
- HttpConnection 實(shí)例代表連接到目標(biāo)服務(wù)器的當(dāng)前連接
- HttpHost 實(shí)例代表連接到目標(biāo)服務(wù)器的當(dāng)前連接
- HttpRoute 實(shí)例代表了完整的連接路由
- HttpRequest 實(shí)例代表了當(dāng)前的HTTP請(qǐng)求嘁锯。
- HttpResponse 實(shí)例代表了當(dāng)前的HTTP響應(yīng)。
- RequestConfig 代表當(dāng)前請(qǐng)求配置。
- java.util.List<URI> 對(duì)象代表一個(gè)含有執(zhí)行請(qǐng)求過(guò)程中所有重定向的地址家乘。
小demo
請(qǐng)求配置在最初被初始化蝗羊,它將在執(zhí)行上下文中一直保持,共享同一個(gè)會(huì)話的所有連續(xù)請(qǐng)求
public static void contextDemo() throws IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
RequestConfig config = RequestConfig
.custom()
.setConnectionRequestTimeout(3000)
.setConnectTimeout(3000)
.setSocketTimeout(3000)
.build();
HttpGet get = new HttpGet("http://www.baidu.com");
get.setConfig(config);
HttpClientContext context = HttpClientContext.create();
CloseableHttpResponse response = httpclient.execute(get, context);
System.out.println(EntityUtils.toString(response.getEntity()));
System.out.println("---------------------------------");
HttpGet get1 = new HttpGet("http://www.qq.com");
get1.setConfig(config);
CloseableHttpResponse res = httpclient.execute(get1, context);
System.out.println(EntityUtils.toString(res.getEntity()));
}
異常處理
HttpClient 能夠拋出兩種類型的異常:
- java.io.IOException ,如socket 連接超時(shí)或被重置的異常仁锯。
- HttpException :標(biāo)志Http請(qǐng)求失敗的信號(hào)耀找,如違反HTTP協(xié)議。
I/O 錯(cuò)誤被認(rèn)為是非致命的和可以恢復(fù)的扑馁,而HTTP協(xié)議錯(cuò)誤涯呻,則被認(rèn)為是致命的而且是不能自動(dòng)恢復(fù)的。
請(qǐng)求嘗試處理器
為了能使用自定義異常的回復(fù)機(jī)制腻要,必須要實(shí)現(xiàn)HttpRequestRetryHandler接口复罐。
小demo
public static void requestRetryDemo() throws IOException {
CloseableHttpClient httpClient = HttpClients
.custom()
.setRetryHandler(DefaultHttpRequestRetryHandler.INSTANCE)
.build();
HttpGet get = new HttpGet("http://www.baidu.com") ;
CloseableHttpResponse response = httpClient.execute(get);
System.out.println(EntityUtils.toString(response.getEntity()));
}
上例中我們使用了默認(rèn)的請(qǐng)求重試類,默認(rèn)重試次數(shù)為三次雄家,requestSentRetryEnabled 為false效诅,當(dāng)然我們也可以自己定制,具體的參數(shù)請(qǐng)自行查閱源碼
請(qǐng)求終止
使用HttpRequest#abort()來(lái)終止線程 ;該方法為線程安全的,可以從任意線程調(diào)用趟济。
重定向處理
重定向的url,通過(guò)HttpContext#getRedirectLocation().獲取重定向網(wǎng)址乱投。
參考: http://blog.csdn.net/u011179993/article/details/47123727
少年聽雨歌樓上,紅燭昏羅帳顷编。
壯年聽雨客舟中戚炫,江闊云低,斷雁叫西風(fēng)媳纬。
感謝支持双肤!
---起個(gè)名忒難