標籤:android http put請求 cookie session
Android之Http通訊——5.開發中遇到的一些問題
標籤(空格分隔): 未分類
本節引言:
好吧,好久沒在這裡更新blog了,不是小豬偷懶了,其實是在忙一些其他的事情,本來這節是應該講解下結合Retrofit來封裝Http請求的,不過,上周在使用基本的HttpClient和HttpURLConnection做項目的時候遇到了兩個問題,糾結了幾天,小豬還是覺得有必要mark一下,分別是Http請求的Cookie問題和像伺服器發送PUT請求的問題,沒錯是“PUT”而不是GET或者POST!
1.Cookie的問題
說到這個Cookie我們要先瞭解一點概念性的東西:Session和Cookie
1)先舉個例子讓大家體會下這個流程吧:
小豬輸入帳號密碼後登陸下學校的教務系統,然後訪問課表資訊成功,然後如果你用的是Chrome,按F12進入開發模式:來到Resources介面可以看到我們的Cookies:
點擊後我們可以看到裡面儲存的內容,由名稱;值;cookie所在的域(domain);cookie所在的目錄(path)Asp.net預設為/即根目錄;到期時間;Cookie大小:
看下我們的要求標頭裡面有個Cookie欄位!
恩呢,現在我們把Cookie清掉(或者等幾分鐘),然後再訪問下述連結:
這時候,頁面竟然自動跳回登陸頁面了!當然一些其他的網站可能會彈出一個對話方塊說“登陸逾時”之類的東西!
2)恩呢,這就是我們Http中的登陸,以及登陸後訪問相關頁面的流程:
一般是登陸的時候:伺服器通過Set-Cookie回應標頭,返回一個Cookie,瀏覽器預設儲存這個Cookie,後續訪問相關頁面的時候會帶上這個Cookie,通過Cookie要求標頭來完成訪問,如果沒Cookie或者Cookie到期,就提示使用者沒登陸,登陸逾時,訪問需要登陸之類的資訊!
3)而我們使用HttpClient和HttpURLConnection其實也就是類比這一個流程,登陸後拿到cookie拿著它去發請求:
HttpURLConnection中:
獲得Cookie:conn.getHeaderField(“Set-Cookie”);
請求時帶上Cookie:conn.setRequestProperty(“Cookie”,cookie);
HttpClient中:
稍微複雜點,要使用到一個HttpResponse:
HttpResponse loginResponse = new DefaultHttpClient().execute(getLogin);
獲得Cookie:cookie = loginResponse.getFirstHeader(“Set-Cookie”).getValue();
請求時帶上Cookie:httpPost.setHeader(“Cookie”, cookie);
好了上述就是HttpURLConnection和HttpClient擷取與請求時帶上Cookie的方法!
另外還有筆者糾結幾天的問題是之前做請求時,服務端日誌一直都是使用者未登入,後來才知道是服務端那邊的人沒對要求標頭進行處理,好吧,然後服務端還一直說我的問題….醉了,另外在糾結的過程中也討論了另外一種折衷的解決方案,“URL重寫”,就是使用一個session id,Get請求的話在基本的請求參數後添加多一個:
…&sessionid=xxxxx這樣,然後他服務端做解析;Post請求的話,在表單中添加一個欄位,程式碼範例如下:
這裡我們用的是JSON字串的形式,接到請求時服務端取出session裡的內容,然後做下查詢即可~
4)最後說回Session和Cookie的區別,Cookie只是Session機制的一種形式,我們也可以使用其他方式來作為用戶端的一個唯一標識,比如上面的“URL重寫”
2.Put請求的處理:
Put請求對於很多朋友來說可能有點陌生,畢竟我們平時接觸的比較多的情況都是GET和POST,一開始小豬也不知道,不過後來才發現和POST其實是差不多的,而且我們只需在POST的基礎上改點東西就可以使用了!而HttpClient也給我們提供了一個HttpPut的API,下面貼下小豬自己項目中寫的請求代碼吧:
HttpURLConnection發送PUT請求範例程式碼如下:
public static String LoginByPut(Context mContext, String mobile, String password, int from, String devid, String version_name, int remember_me) { String resp = ""; try { HttpURLConnection conn = (HttpURLConnection) new URL(LOGIN_URL).openConnection(); conn.setRequestMethod("PUT"); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); String data = "mobile=" + mobile + "&password=" + password + "&from=" + from + "&devid=" + "devid" + "&version_name=" + "version_name" + "&remember_me=" + remember_me; ; // 擷取輸出資料流: OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(data); writer.flush(); writer.close(); // 擷取相應流對象: InputStream in = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) response.append(line); SPUtils.put(mContext, "session", conn.getHeaderField("Set-Cookie")); // 資源釋放: in.close(); // 返回字串 Log.e("HEHE", response.toString()); return response.toString(); } catch (Exception e) { e.printStackTrace(); } ; return "";}
使用HttpPut發送Put請求:
public static int PutActCode(String actCode, String licPlate, Context mContext) { int resp = 0; String cookie = (String) SPUtils.get(mContext, "session", ""); HttpPut httpPut = new HttpPut(PUTACKCODE_URL); httpPut.setHeader("Cookie", cookie); try { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("activation_code", actCode)); params.add(new BasicNameValuePair("license_plate", licPlate)); httpPut.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); HttpResponse course_response = new DefaultHttpClient().execute(httpPut); if (course_response.getStatusLine().getStatusCode() == 200) { HttpEntity entity2 = course_response.getEntity(); JSONObject jObject = new JSONObject(EntityUtils.toString(entity2)); resp = Integer.parseInt(jObject.getString("status_code")); return resp; } } catch (Exception e) { e.printStackTrace(); } return resp;}
3.小結:
好吧,內容還是比較簡單的,其實核心就是如何擷取Cookie以及發送請求的時候帶上我們的Cookie,當然有些公司可能不是用的Http協議的Session來標識使用者,而是使用oAuth協議,後續公司如果用到再深入研究;還說了下Put請求怎麼寫!嗯,下節見~
轉載請註明出處:coder-pig,謝謝,請勿用於商業用途,侵權必究~
Android之Http通訊——5.開發中遇到的一些問題