Android使用OkHttp進(jìn)行重定向攔截處理的方法
網(wǎng)上有很多的OkHttp的教程,但是并沒(méi)有一個(gè)是關(guān)于如何OkHttp處理重定向的。這里的處理重定向的意思是:把重定向請(qǐng)求攔截下來(lái),然后我們自己去請(qǐng)求重定向后的網(wǎng)頁(yè),然后通過(guò)Jsoup解析自己需要的網(wǎng)頁(yè)數(shù)據(jù)。比如說(shuō)我們模擬用戶(hù)登錄,然后自己去請(qǐng)求解析登陸后跳轉(zhuǎn)的網(wǎng)頁(yè)的內(nèi)容。為什么要做這樣的一個(gè)東西呢?比如說(shuō)課程表的查成績(jī)功能,就可以使用這種方法來(lái)獲取成績(jī)。
大概的原理是怎樣的呢?
我們先來(lái)說(shuō)一下瀏覽器是怎么樣做用戶(hù)登錄的:瀏覽器會(huì)將你輸入的帳號(hào)和密碼通過(guò)POST請(qǐng)求攜帶過(guò)去,當(dāng)然可能還會(huì)有其它字段,因?yàn)檫@個(gè)POST請(qǐng)求是我們網(wǎng)頁(yè)和服務(wù)器規(guī)定好的;登錄成功后,服務(wù)器會(huì)返回一個(gè)Set-Cookie請(qǐng)求頭字段,有了Cookie瀏覽器就可以通過(guò)GET請(qǐng)求訪問(wèn)登錄后的網(wǎng)頁(yè),注意沒(méi)有這個(gè)Cookie是無(wú)法請(qǐng)求登陸后的網(wǎng)頁(yè)的,GET請(qǐng)求必須設(shè)置Cookie請(qǐng)求頭字段,將服務(wù)器返回的Cookie攜帶過(guò)去。
明白了瀏覽器的行為之后,我們知道需要做的步驟就是4步:
- 自己做POST請(qǐng)求,并且不讓它自動(dòng)重定向
- 我們拿到POST請(qǐng)求返回來(lái)的響應(yīng),獲取對(duì)應(yīng)的Set-Cookie字段的內(nèi)容
- 將該對(duì)應(yīng)的內(nèi)容添加到GET請(qǐng)求的Cookie請(qǐng)求頭字段中,然后做GET請(qǐng)求
- 獲取到的GET請(qǐng)求的響應(yīng)體就是我們登陸后的網(wǎng)頁(yè)內(nèi)容了,如果是靜態(tài)網(wǎng)頁(yè)可以通過(guò)Jsoup解析自己想要的信息了
我們需要通過(guò)抓包或者Chorme瀏覽器自帶的請(qǐng)求查看功能來(lái)查看POST請(qǐng)求提交的表單是怎樣的。Chorme按F12即可
輸入帳號(hào)密碼點(diǎn)擊登錄即可
點(diǎn)擊登陸后我們可以看到,控制面板出現(xiàn)了一堆訪問(wèn)的記錄,第一個(gè)就是我們要找的,第一個(gè)的Status標(biāo)志是302,302是重定向的意思。我們點(diǎn)擊(pass.asp)這個(gè)請(qǐng)求,然后查看它的POST的請(qǐng)求頭(點(diǎn)擊Headers)。
我們看到了一堆的Set-Cookie字段,字段對(duì)應(yīng)的內(nèi)容就是我們要攜帶做GET請(qǐng)求的
同時(shí)我們可以看到POST提交的表單內(nèi)容,有些網(wǎng)站的提交參數(shù)是經(jīng)過(guò)加密的,如果要做通用的,我們需要找到它加密的方法,做同樣的加密處理。
接下來(lái)使用OkHttp進(jìn)行操作
由于OkHttp提供了自動(dòng)攜帶Cookie進(jìn)行請(qǐng)求的功能,于是我們可以很方便地進(jìn)行處理了。
final OkHttpClient client = new OkHttpClient().newBuilder() .followRedirects(false) //禁制OkHttp的重定向操作,我們自己處理重定向 .followSslRedirects(false) .cookieJar(new LocalCookieJar()) //為OkHttp設(shè)置自動(dòng)攜帶Cookie的功能 .build(); //CookieJar是用于保存Cookie的 class LocalCookieJar implements CookieJar{ List<Cookie> cookies; @Override public List<Cookie> loadForRequest(HttpUrl arg0) { if (cookies != null) return cookies; return new ArrayList<Cookie>(); } @Override public void saveFromResponse(HttpUrl arg0, List<Cookie> cookies) { this.cookies = cookies; } }
為什么設(shè)置CookieJar就能自動(dòng)攜帶Cookie了呢?給你看一段OkHttp的源碼就知道了。
/** * Populates request with defaults and cookies. * * <p>This client doesn't specify a default {@code Accept} header because it doesn't know what * content types the application is interested in. */ private Request networkRequest(Request request) throws IOException { Request.Builder result = request.newBuilder(); //如果CookieJar的Cookie不為空,則設(shè)置Cookie字段 List<Cookie> cookies = client.cookieJar().loadForRequest(request.url()); if (!cookies.isEmpty()) { result.header("Cookie", cookieHeader(cookies)); } return result.build(); }
于是接下來(lái)我們就是做POST請(qǐng)求了
final OkHttpClient client = new OkHttpClient().newBuilder() .followRedirects(false) .followSslRedirects(false) .cookieJar(new LocalCookieJar()) .build(); //構(gòu)造一個(gè)POST請(qǐng)求 RequestBody body = new FormBody.Builder().add("UserStyle", "student") .add("user", "xxx").add("password", "xxx").build(); Request request = new Request.Builder().url("http://222.195.8.201/pass.asp").post(body).build(); client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { /** * 如果不用CookieJar,那么就要自己去解析返回的Set-Cookie字段,解析之后通過(guò)addHeader("Cookie", cookie) * 添加Cookie請(qǐng)求頭 */ // List<String> cookies = response.headers("Set-Cookie"); // String cookie = ""; // for(int i=cookies.size()-1; i>=0; i--){ // cookie = cookie+ cookies.get(i).replace("path=/", "") + " "; // } //做GET請(qǐng)求 Request redirectRequest = new Request.Builder().url("http://222.195.8.201/student/asp/Select_Success.asp") // .addHeader("Cookie", cookie) .build(); //拿到登陸后操作的某個(gè)網(wǎng)頁(yè)的內(nèi)容 Response response2 = client.newCall(redirectRequest).execute(); String result = response2.body().string(); System.out.println(result); } @Override public void onFailure(Call arg0, IOException arg1) { } });
拿到內(nèi)容后就可以自己進(jìn)行內(nèi)容的解析和展示了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android okhttp的啟動(dòng)流程及源碼解析
- Retrofit和OkHttp如何實(shí)現(xiàn)Android網(wǎng)絡(luò)緩存
- Java/Android 實(shí)現(xiàn)簡(jiǎn)單的HTTP服務(wù)器
- Android Studio OkHttpClient使用教程詳解
- Android :okhttp+Springmvc文件解析器實(shí)現(xiàn)android向服務(wù)器上傳照片
- Android webview加載https鏈接錯(cuò)誤或無(wú)響應(yīng)的解決
- android 使用okhttp可能引發(fā)OOM的一個(gè)點(diǎn)
- Android Okhttp斷點(diǎn)續(xù)傳面試深入解析
- Android使用OkHttp發(fā)送post請(qǐng)求
- Android基于OkHttp實(shí)現(xiàn)下載和上傳圖片
- Android使用 Coroutine + Retrofit打造簡(jiǎn)單的HTTP請(qǐng)求庫(kù)
相關(guān)文章
Android HTTP發(fā)送請(qǐng)求和接收響應(yīng)的實(shí)例代碼
Android HTTP請(qǐng)求和接收響應(yīng)實(shí)例完整的Manifest文件如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-06-06Android實(shí)用的Toast工具類(lèi)封裝
這篇文章主要為大家詳細(xì)介紹了Android實(shí)用Toast工具類(lèi)的封裝,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android手機(jī)開(kāi)發(fā)設(shè)計(jì)之記事本功能
這篇文章主要為大家詳細(xì)介紹了Android手機(jī)開(kāi)發(fā)設(shè)計(jì)之記事本功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05通過(guò)WIFI(不用數(shù)據(jù)線)連接Android手機(jī)調(diào)試
本文主要介紹WIFI 鏈接手機(jī)調(diào)試,這里詳細(xì)介紹了WIFI 鏈接Android手機(jī)實(shí)現(xiàn)調(diào)試的過(guò)程,有需要的小伙伴可以參考下2016-08-08Android實(shí)現(xiàn)獲取簽名及公鑰的方法
這篇文章主要介紹了Android實(shí)現(xiàn)獲取簽名及公鑰的方法,可實(shí)現(xiàn)Android通過(guò)包名獲取相關(guān)簽名及公鑰的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android自定義軟鍵盤(pán)的設(shè)計(jì)與實(shí)現(xiàn)代碼
本篇文章主要介紹了 Android自定義軟鍵盤(pán)的設(shè)計(jì)與實(shí)現(xiàn)代碼,有需要的可以了解一下。2016-11-11Android單選按鈕對(duì)話(huà)框用法實(shí)例分析
這篇文章主要介紹了Android單選按鈕對(duì)話(huà)框用法,以完整實(shí)例形式分析布局及對(duì)話(huà)框類(lèi)的相關(guān)使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09Android編程實(shí)現(xiàn)應(yīng)用強(qiáng)制安裝到手機(jī)內(nèi)存的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)應(yīng)用強(qiáng)制安裝到手機(jī)內(nèi)存的方法,涉及Android中屬性設(shè)置的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11