Android之Http通訊——5.開發中遇到的一些問題

來源:互聯網
上載者:User

標籤: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.開發中遇到的一些問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.