OkHttp3簡單的使用說明(Cookie管理)

作者:Zyao89焕蹄;轉載請保留此行酬蹋,謝謝身笤;


上一篇文章寫的是 Retrofit2.2說明-簡單使用糖声,文中主要介紹的是Retrofit的簡單使用方法斤彼,具體涉及到的網絡請求方面的內容,在這里一并介紹姨丈。

Retrofit與okhttp共同出自于Square公司畅卓,retrofit就是對okhttp做了一層封裝。網絡請求依賴Okhttp蟋恬,我們現(xiàn)在通過一些栗子翁潘,對OkHttp進行一定的了解。

首先說下OkHttp3是Java和Android都能用歼争,Android還有一個著名網絡庫叫Volley拜马,那個只有Android能用渗勘。

引入

    compile 'com.squareup.okhttp3:okhttp:3.6.0'

初始化

mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .authenticator(new Authenticator()
                {
                    @Override
                    public Request authenticate(Route route, Response response) throws IOException
                    {//401,認證
                        String credential = Credentials.basic("zyao89", "password1");
                        return response.request().newBuilder().header("Authorization", credential).build();
                    }
                })
                .cookieJar(new CookieJar()
                {//這里可以做cookie傳遞俩莽,保存等操作
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies)
                    {//可以做保存cookies操作
                        System.out.println("cookies url: " + url.toString());
                        for (Cookie cookie : cookies)
                        {
                            System.out.println("cookies: " + cookie.toString());
                        }
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url)
                    {//加載新的cookies
                        ArrayList<Cookie> cookies = new ArrayList<>();
                        Cookie cookie = new Cookie.Builder()
                                .hostOnlyDomain(url.host())
                                .name("SESSION").value("zyao89")
                                .build();
                        cookies.add(cookie);
                        return cookies;
                    }
                })
                .build();
  • authenticator() 此方法可進行請求認證操作旺坠。
  • cookieJar () 次方法可進行cookies保留,和自定義cookies扮超。(可用于存儲sessionID等信息取刃,保存鏈接身份)

Get請求

  • 異步
public void get()
    {
        Request request = new Request.Builder()
                .url("http://200.200.200.182:9999/login")
                .build();

        Call call = mOkHttpClient.newCall(request);
        call.enqueue(getCallback());
    }
/**
     * 請求回調
     * @return
     */
    private Callback getCallback()
    {
        return new Callback()
        {//子線程回調
            @Override
            public void onResponse(Call call, Response response)
            {
                printLogCat("Code: " + response.code());
                printLogCat("Message: " + response.message());

                if (response.isSuccessful())
                {
                    try
                    {
                        printLogCat("Body: " + response.body().string());
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                        printLogCat("ERROR: " + "response'body is error");
                    }
                }
                else
                {
                    printLogCat("ERROR: " + "okHttp is request error");
                }
                printLogCat("");
            }

            @Override
            public void onFailure(Call call, IOException e)
            {
                printLogCat("ERROR: " + e.getMessage());
                printLogCat("");
            }
        };
    }
  • 同步
public void getSyc()
    {
        new Thread(new Runnable() {
            @Override
            public void run()
            {
                Request request = new Request.Builder()
                        .url("http://200.200.200.182:9999/login")
                        .build();
                Call call = mOkHttpClient.newCall(request);
                try
                {
                    Response response = call.execute();
                    sycCallback(response);
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }).start();
    }
private void sycCallback(Response response)
    {
        printLogCat("Code: " + response.code());
        printLogCat("Message: " + response.message());

        if (response.isSuccessful())
        {
            try
            {
                printLogCat("Body: " + response.body().string());
            }
            catch (IOException e)
            {
                e.printStackTrace();
                printLogCat("ERROR: " + "response'body is error");
            }
        }
        else
        {
            printLogCat("ERROR: " + "okHttp is request error");
        }
        printLogCat("");
    }

response的body有很多種輸出方法,string()只是其中之一出刷,注意是string()不是toString()璧疗。如果是下載文件就是response.body().bytes()
另外可以根據(jù)response.code()獲取返回的狀態(tài)碼馁龟。

Post請求

同步異步都與get方法一致崩侠,后面提供異步栗子:

public void post()
    {
        String data = "{\"username\" : \"admin\", \"password\" : \"12345\"}";
        RequestBody requestBody = RequestBody.create(JSON, data);
        Request request = new Request.Builder()
                .url("http://200.200.200.182:9999/login")
                .post(requestBody)
                .build();

        Call call = mOkHttpClient.newCall(request);
        call.enqueue(getCallback());
    }

RequestBody的數(shù)據(jù)格式都要指定Content-Type,常見的有:

  • application/x-www-form-urlencoded 數(shù)據(jù)是個普通表單
  • multipart/form-data 數(shù)據(jù)里有文件
  • application/json 數(shù)據(jù)是個Json
  • text/x-markdown 文本MarkDown

除了RequestBody坷檩,也可用FormBody(繼承于RequestBody)却音,如:

RequestBody formBody = new FormBody.Builder()
                .add("username", "admin2")
                .add("password", "12222333")
                .add("message", "zyao89")
                .build();

從源碼中可看到,FormBody中已指定Content-Type格式為application/x-www-form-urlencoded

private static final MediaType CONTENT_TYPE =
      MediaType.parse("application/x-www-form-urlencoded");

假如是個Json數(shù)據(jù)矢炼,則:

private static final MediaType JSON = 
      MediaType.parse("application/json; charset=utf-8");

圖片文件數(shù)據(jù)系瓢,則:

public void postFile(File file)
    {
        MultipartBody multipartBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
                .build();
        Request request = new Request.Builder()
                .url("http://200.200.200.182:9999/file")
                .post(multipartBody)
                .build();

        Call call = mOkHttpClient.newCall(request);
        call.enqueue(getCallback());
    }

MultipartBody也是繼承了RequestBody,從源碼可知它適用于這五種Content-Type:

  public static final MediaType MIXED = MediaType.parse("multipart/mixed");

  public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative");

  public static final MediaType DIGEST = MediaType.parse("multipart/digest");

  public static final MediaType PARALLEL = MediaType.parse("multipart/parallel");

  public static final MediaType FORM = MediaType.parse("multipart/form-data");

MediaType類型可參考W3Scholl MIME 參考手冊

PUT \ DELETE 等其它請求

這里只對PUT舉個栗子裸删,其它類型差不多八拱。

    public void put()
    {
        FormBody formBody = new FormBody.Builder()
                .add("username", "admin2")
                .add("password", "12222333")
                .add("message", "zyao89")
                .build();
        Request request = new Request.Builder()
                .url("http://200.200.200.182:9999/put")
                .header("Accept", "application/json; q=0.5")//添加請求頭,方式一
                .addHeader("Accept", "*")//添加請求頭涯塔,方式二
                .put(formBody)
                .build();

        Call call = mOkHttpClient.newCall(request);

        call.enqueue(getCallback());
    }

上面栗子中肌稻,Request在創(chuàng)建時,可自行增加header請求頭:

.header("Accept", "application/json; q=0.5")//添加請求頭匕荸,方式一
.addHeader("Accept", "*")//添加請求頭爹谭,方式二

客戶端Cookie 與 服務器Session 自動管理

業(yè)務中經常出現(xiàn)客戶端登錄請求結束后,服務端會返回一個帶有唯一登錄認證信息Session的Response榛搔,其中Session就藏在Cookie中诺凡,那么如何讓下一次Request請求創(chuàng)建時,可以將這個認證信息放入其中呢践惑?

OkHttp為我們提供了簡便的管理方法腹泌,可自動攜帶,保存和更新Cookie信息尔觉;方法如下:

//cookie存儲
private ConcurrentHashMap<String, List<Cookie>> cookieStore = new ConcurrentHashMap<>();

mOkHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJar()
                {//這里可以做cookie傳遞凉袱,保存等操作
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies)
                    {//可以做保存cookies操作
                        cookieStore.put(url.host(), cookies);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url)
                    {//加載新的cookies
                        List<Cookie> cookies = cookieStore.get(url.host());
                        return cookies != null ? cookies : new ArrayList<Cookie>();
                    }
                })
                .build();

如此設置后,在同一個域名地址情況下,發(fā)送Request都不用管理Cookie了专甩,并且可以通過cookieStore獲取已存儲的Cookie钟鸵,如此可達到自動管理。

Demo演示圖

測試Demo演示圖

Github項目地址:zyao89/DemoOkHttp

個人博客:http://zyao89.me

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末涤躲,一起剝皮案震驚了整個濱河市棺耍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌种樱,老刑警劉巖蒙袍,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異缸托,居然都是意外死亡左敌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門俐镐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哺哼,你說我怎么就攤上這事佩抹。” “怎么了取董?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵棍苹,是天一觀的道長。 經常有香客問我茵汰,道長枢里,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任蹂午,我火速辦了婚禮栏豺,結果婚禮上,老公的妹妹穿的比我還像新娘豆胸。我一直安慰自己奥洼,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布晚胡。 她就那樣靜靜地躺著灵奖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪估盘。 梳的紋絲不亂的頭發(fā)上瓷患,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音遣妥,去河邊找鬼擅编。 笑死,一個胖子當著我的面吹牛燥透,可吹牛的內容都是我干的沙咏。 我是一名探鬼主播辨图,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼肢藐!你這毒婦竟也來了故河?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤吆豹,失蹤者是張志新(化名)和其女友劉穎鱼的,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痘煤,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡凑阶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了衷快。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宙橱。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蘸拔,靈堂內的尸體忽然破棺而出师郑,到底是詐尸還是另有隱情,我是刑警寧澤调窍,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布宝冕,位于F島的核電站,受9級特大地震影響邓萨,放射性物質發(fā)生泄漏地梨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一缔恳、第九天 我趴在偏房一處隱蔽的房頂上張望宝剖。 院中可真熱鬧,春花似錦褐耳、人聲如沸诈闺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雅镊。三九已至,卻和暖如春刃滓,著一層夾襖步出監(jiān)牢的瞬間仁烹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工咧虎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卓缰,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像征唬,于是被迫代替她去往敵國和親捌显。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容

  • 參考Android網絡請求心路歷程Android Http接地氣網絡請求(HttpURLConnection) 一...
    合肥黑閱讀 21,274評論 7 63
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理总寒,服務發(fā)現(xiàn)扶歪,斷路器,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 這篇文章主要總結Android著名網絡框架-okhttp的基礎使用摄闸。 okhttp是什么 okhttp是Andro...
    磨礪營IT閱讀 726評論 0 1
  • 參考資源 官網 國內博客 GitHub官網 鑒于一些關于OKHttp3源碼的解析文檔過于碎片化善镰,本文系統(tǒng)的,由淺入...
    風骨依存閱讀 12,503評論 11 82
  • 閑著沒事干或者實在不知道畫什么的時候年枕,畫人體總是沒錯的炫欺! 畫畫最基本的就是了解結構。 畫人更是如此熏兄,人體結構不理解...
    奈何zh閱讀 218評論 4 7