關於Http請求Cookie問題
在Http請求中,很多時候我們要設定Cookie和獲取返回的Cookie,在這個問題上踩了一個很大的坑,主要是兩個問題:
1.不能獲取到重定向返回的Cookie;
2.兩次請求返回的Cookie是相同的;
(介面是蘇寧登入的介面,是用ids_r_me兌換authId的,這是單點登入常見的方式)後來我花了一點時間把幾種不同的包中的坑總結一下:
第一個:apache下在httpclient
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency>
這個包在獲取重定向Cookie時,會存在丟失Cookie的情況,這個包沒有提供獲取Cookie的藉口方法,只能是通過Header獲取Cookie和Set-Cookie獲取返回的Cookie,用這個包傳送Http請求好像沒有儲存重定向的Cookie,過程中肯定是有用到的,但是沒有對外提供獲取Cookie的介面,程式碼如下:
1/** 2* apache httpclient 4.5.6 test redirect Cookie 3*/ 4@Test 5public void Test_2() throws IOException { 6List<String> list = new ArrayList(); 7list.add("NjIyMDY5MDk1M19CUk9XU0VSXz**********************************18wXzQ2OWM1ZjI3 NDdjN2RmYzRiZWI3Njg3MDllNzI3MmFj"); 8list.add("NzEwNDIyNjQwN19CUk9XU0VSXz**********************************M18wX2JiZWQ5YmVkMjJiOTAyZDNjYmNkZTk4NGM0NmFiYmMz"); 9String url = "https://passport.suning.com/ids/login?service=https%3A%2F%2Fmy.suning.com%2Fmsi-web%2Fauth%3FtargetUrl%3Dhttps%253A%252F%252Floginst.suning.com%252FauthStatus%253F_%253D1540179466121%2526callback%253DZepto1540179465802"; 10 11for (String token : list) { 12HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); 13CloseableHttpClient httpClient = httpClientBuilder.build(); 14HttpGet httpGet = new HttpGet(url); 15httpGet.setHeader("Cookie", "ids_r_me=" + token); 16CloseableHttpResponse response = httpClient.execute(httpGet); 17org.apache.http.Header[] headers = response.getAllHeaders(); 18for (org.apache.http.Header header : headers) { 19System.out.println(header.getName() + "=" + header.getValue()); 20} 21System.out.println(EntityUtils.toString(response.getEntity()) ); 22} 23}
因為沒有找到獲取Cookie的介面,所以列印了所有的header。
第二個:hutool
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.2.1</version> </dependency>
這個包預設是可以獲取Cookie的,但是開始遇到的問題是,第二次請求時獲取的Cookie和第一次一樣,因為這個包中的cookieManager 是一個靜態變數,但是第二次請求應該會覆蓋掉才對,具體為什麼不回覆蓋沒有再深追,後來找到了它提供的一個清空cookieManager 中cookieStore的方法,問題就解決了。兩次請求獲取的是正常的Cookie。程式碼如下:
1/** 2* Hutool 4.2.1 test redirect Cookie 3*/ 4@Test 5public void Test_1() { 6List<String> list = new ArrayList(); 7list.add("NjIyMDY5MDk1M19CUk9XU0VSXz**********************************18wXzQ2OWM1ZjI3 NDdjN2RmYzRiZWI3Njg3MDllNzI3MmFj"); 8list.add("NzEwNDIyNjQwN19CUk9XU0VSXz**********************************M18wX2JiZWQ5YmVkMjJiOTAyZDNjYmNkZTk4NGM0NmFiYmMz"); 9String url = "https://passport.suning.com/ids/login?service=https%3A%2F%2Fmy.suning.com%2Fmsi-web%2Fauth%3FtargetUrl%3Dhttps%253A%252F%252Floginst.suning.com%252FauthStatus%253F_%253D1540179466121%2526callback%253DZepto1540179465802"; 10for (String token : list) { 11 12HttpRequest request = HttpUtil.createGet(url); 13Map header = new HashMap(); 14header.put("Cookie", "ids_r_me=" + token); 15request = request.addHeaders(header); 16 17HttpResponse response = request.execute(); 18 19List<HttpCookie> cookieList = response.getCookies(); 20System.out.println("Cookie:"); 21for (HttpCookie cookie : cookieList) { 22System.out.println(cookie.getName() + "=" + cookie.getValue()); 23} 24HttpRequest.getCookieManager().getCookieStore().removeAll(); 25} 26}
其中第24行是清除本次請求中的Cookie,如果放在response.getCookies()之前,就不能獲取到Cookie了,所以應該是獲取到Cookie後,清除本次請求的Cookie。
第三個:commons-httpclient
<dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency>
這個包傳送請求返回的有點奇怪,但是習慣了感覺好像也挺合理,程式碼如下:
1/** 2* commons-httpclient 3.1 test redirect Cookie 3* 4* @throws IOException 5*/ 6@Test 7public void Test_3() throws IOException { 8List<String> list = new ArrayList(); 9list.add("NjIyMDY5MDk1M19CUk9XU0VSXz**********************************18wXzQ2OWM1ZjI3 NDdjN2RmYzRiZWI3Njg3MDllNzI3MmFj"); 10list.add("NzEwNDIyNjQwN19CUk9XU0VSXz**********************************M18wX2JiZWQ5YmVkMjJiOTAyZDNjYmNkZTk4NGM0NmFiYmMz"); 11String url = "https://passport.suning.com/ids/login?service=https%3A%2F%2Fmy.suning.com%2Fmsi-web%2Fauth%3FtargetUrl%3Dhttps%253A%252F%252Floginst.suning.com%252FauthStatus%253F_%253D1540179466121%2526callback%253DZepto1540179465802"; 12for (String token : list) { 13HttpClient httpClient = new HttpClient(); 14GetMethod getMethod = new GetMethod(url); 15 16getMethod.setRequestHeader(new Header("Cookie", "ids_r_me=" + token)); 17Integer state = httpClient.executeMethod(getMethod); 18Cookie[] cookieArray = httpClient.getState().getCookies();19for (Cookie cookie : cookieArray) { 20System.out.println(cookie.getName() + "=" + cookie.getValue()); 21} 22System.out.println("responseBody:"+getMethod.getResponseBodyAsString()); 23} 24}
其中第17行返回的是本次請求的狀態碼,第22行是獲取本次請求返回內容。