HttpClient 與 HttpURLConnection 共用 SessionId
HttpClient 與 HttpUrlConnection 是Android 中HTTP操作最常見的訪問方式。在一個應用程序中有時候會用到這兩種方式,如何能讓他們共用Cookie,讓客戶端訪問服務器保持Session進行通信。
針對httpClient 和HttpUrlConnection 獲取和發送Cookie,主要是sessionID的共享。
httpClient獲取及發送Session 值:
HttpPost httpPost = new HttpPost(url);
// 將SessionId發給服務器
if(null != mSESSIONID){
httpPost.setHeader("Cookie", "SESSIONID=" + mSESSIONID);
}
DefaultHttpClient httpClient = new DefaultHttpClient();
httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = httpResponse.getEntity();
CookieStore mCookieStore = httpClient.getCookieStore();
List<Cookie> cookies = mCookieStore.getCookies();
//這裏是讀取指定Cookie 的值
for (int i = 0; i < cookies.size(); i++) {
if ("SESSIONID".equals(cookies.get(i).getName())) {
mSESSIONID = cookies.get(i).getValue();
break;
}
}
}
在程序中保存上面的sessionId ,或用全局變量,或者SharedPreferences 保存,看這個sessionId 的會話時間及程序業務。
HttpUrlConnection 獲取及發送Session 值:
HttpURLConnection url_con = null;
URL url = new URL(reqUrl);
url_con = (HttpURLConnection) url.openConnection();
//設置session
if (mSESSIONID!= null) {
url_con.setRequestProperty("Cookie","JSESSIONID="+mSESSIONID);
}
...
String cookieVal =con.getHeaderField("Set-Cookie");
// 獲取session
if (cookieVal != null) {
StringmSESSIONID= cookieVal.substring(0, cookieVal.indexOf(";"));
}
HttpURLConnection url_con = null;
HttpURLConnection和HttpClient比較(Android):
HttpURLConnection和HttpClient 都支持HTTPS協議、IPv6、以流的形式進行上傳和下載、配置超時時間、以及連接池等功能。
DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具體的實現類,它們都擁有衆多的API,而且實現比較穩定,bug數量也很少。但同時也由於HttpClient的API數量過多,使得我們很難在不破壞兼容性的情況下對它進行升級和擴展,所以目前Android團隊在提升和優化HttpClient方面的工作態度並不積極。
HttpURLConnection是一種多用途、輕量極的HTTP客戶端,使用它來進行HTTP操作可以適用於大多數的應用程序。雖然HttpURLConnection的API提供的比較簡單,但是同時這也使得我們可以更加容易地去使用和擴展它。不過在Android 2.2版本之前,HttpURLConnection一直存在着一些令人厭煩的bug。比如說對一個可讀的InputStream調用close()方法時,就有可能會導致連接池失效了。那麼我們通常的解決辦法就是直接禁用掉連接池的功能:
在Android 2.3版本中還增加了一些HTTPS方面的改進,現在HttpsURLConnection會使用SNI(Server Name Indication)的方式進行連接,使得多個HTTPS主機可以共享同一個IP地址。除此之外,還增加了一些壓縮和會話的機制。如果連接失敗,它會自動去嘗試重新進行連接。這使得HttpsURLConnection可以在不破壞老版本兼容性的前提下,更加高效地連接最新的服務器。
在Android 4.0版本中,我們又添加了一些響應的緩存機制。當緩存被安裝後(調用HttpResponseCache的install()方法),所有的HTTP請求都會滿足以下三種情況:
1.所有的緩存響應都由本地存儲來提供。因爲沒有必要去發起任務的網絡連接請求,所有的響應都可以立刻獲取到。
2.視情況而定的緩存響應必須要有服務器來進行更新檢查。比如說客戶端發起了一條類似於 “如果/foo.png這張圖片發生了改變,就將它發送給我” 這樣的請求,服務器需要將更新後的數據進行返回,或者返回一個304 Not Modified狀態。如果請求的內容沒有發生,客戶端就不會下載任何數據。
3.沒有緩存的響應都是由服務器直接提供的。這部分響應會在稍後存儲到響應緩存中。
由於這個功能是在4.0之後的版本纔有的,通常我們就可以使用反射的方式來啓動響應緩存功能。下面的示例代碼展示瞭如何在Android 4.0及以後的版本中去啓用響應緩存的功能,同時還不會影響到之前的版本:
private void enableHttpResponseCache() {
try {
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
File httpCacheDir = new File(getCacheDir(), "http");
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {
}
}
你也應該同時配置一下你的Web服務器,在HTTP響應上加入緩存的消息頭。哪一種纔是最好的?
在Android 2.2版本之前,HttpClient擁有較少的bug,因此使用它是最好的選擇。
而在Android 2.3版本及以後,HttpURLConnection則是最佳的選擇。它的API簡單,體積較小,因而非常適用於Android項目。壓縮和緩存機制可以有效地減少網絡訪問的流量,在提升速度和省電方面也起到了較大的作用。對於新的應用程序應該更加偏向於使用HttpURLConnection。