HttpClient 重定向 302
阿新 • • 發佈:2018-12-25
使用HttpClient訪問http地址,有時候會報302錯誤。
通過上網搜尋,發現問題所在,報302是因為訪問的http地址在服務端做了訪問重定向,需要請求重定向後的URI。
1.簡單例項,http訪問返回302,此時需要獲取重定向地址,繼續進行重定向訪問,以獲取最終結果:
public class TestLogin { public static void main(String args[]) { try { HttpClient client = HttpClients.createDefault(); login(client); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void login(HttpClient client) throws Exception { final String APPLICATION_JSON = "application/json"; final String CONTENT_TYPE_TEXT_JSON = "text/json"; String url = "http://172.16.30.208:8092/svc/login"; String js = "{\"username\":\"13800000002\",\"password\":\"123456\"}"; HttpPost httpPost = new HttpPost(url); httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); StringEntity se = new StringEntity(js); se.setContentType(CONTENT_TYPE_TEXT_JSON); httpPost.setEntity(se); HttpResponse response = null; response = client.execute(httpPost); //----------判斷是否重定向開始 int code = response.getStatusLine().getStatusCode(); String newuri = ""; if (code == 302) { Header header = response.getFirstHeader("location"); // 跳轉的目標地址是在 HTTP-HEAD 中的 newuri = header.getValue(); // 這就是跳轉後的地址,再向這個地址發出新申請,以便得到跳轉後的資訊是啥。 System.out.println(newuri); System.out.println(code); httpPost = new HttpPost(newuri); httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); se = new StringEntity(js); se.setContentType(CONTENT_TYPE_TEXT_JSON); httpPost.setEntity(se); response = client.execute(httpPost); code = response.getStatusLine().getStatusCode(); System.out.println("login" + code); } //------------重定向結束 HttpEntity entity = null; entity = response.getEntity(); String s2 = EntityUtils.toString(entity, "UTF-8"); System.out.println(s2); } }
2.複雜例項,來自網路:
需要引導使用者開啟授權頁面進行授權
1). 直接獲取資料,傳遞使用者賬號;
2). 沒有登陸直接去訪問會跳轉到登陸頁面;
3). 登陸了之後,會有個授權頁面,需要手動去點選授權按鈕才真正跳轉;
/** * <pre> * 模擬需要登陸之後才能訪問第三方網站 * 並且需要一些人工參與的操作 * </pre> */ public class Test { private String userName = "我是使用者名稱"; private String password = "我是密碼"; public void loginNext() throws IOException { BasicCookieStore cookieStore = new BasicCookieStore(); // 全域性用這一個httpClient物件模擬真實的一個瀏覽器中操作 CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build(); try { // 模擬使用者登入 HttpPost httpLogin = new HttpPost("xxxxxxxxxxxxxx/index.php/auth/auth/login");// 指向一個沒有驗證碼的登入頁面 List<NameValuePair> nvps = new ArrayList<>(); nvps.add(new BasicNameValuePair("username", userName));// 使用者名稱對應的key nvps.add(new BasicNameValuePair("password", MD5Coder.md5Encode(password)));// 密碼對應的key httpLogin.setEntity(new UrlEncodedFormEntity(nvps)); CloseableHttpResponse respLogin = httpClient.execute(httpLogin); try { HttpEntity entity = respLogin.getEntity(); out.println("respLogin------------>>" + respLogin.toString()); out.println("Login form get: " + respLogin.getStatusLine()); EntityUtils.consume(entity); out.println("Initial set of cookies:"); List<Cookie> cookies = cookieStore.getCookies(); if (cookies.isEmpty()) { out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { out.println("Cookie-" + i + "==" + cookies.get(i).toString()); } } } finally { respLogin.close(); } // 利用會話保持,繼續訪問目標地址 HttpGet httpGetAuth = new HttpGet("xxxxxxxxxxxxxxx/index.php/Auth/Auth/auth?app_id=xxxxxx&redirect_uri=回撥地址&response_type=code"); CloseableHttpResponse respAuth = httpClient.execute(httpGetAuth); String entityAuthStr = ""; try { out.println(respAuth.getStatusLine()); HttpEntity entityAuth = respAuth.getEntity(); entityAuthStr = EntityUtils.toString(entityAuth); out.println("get Auth cookies:"); List<Cookie> cookies = cookieStore.getCookies(); if (cookies.isEmpty()) { out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { out.println("- " + cookies.get(i).toString()); } } out.println("訪問目標地址的結果--------------------->>" + entityAuthStr);//把結果打印出來看一下 EntityUtils.consume(entityAuth); } finally { respAuth.close(); } // 解析登陸之後訪問目標地址的html頁面 獲取目標form表單元素 Document doc = Jsoup.parseBodyFragment(entityAuthStr); String title = doc.title(); out.println("title-------->>" + title); Element element = doc.body(); Elements form = element.select("[name='authForm']");// 授權的form表單 out.println(form); String actionUrl = form.attr("action"); String app_id = element.select("[name='app_id']").val(); String redirect_uri = element.select("[name='redirect_uri']").val(); String state = element.select("[name='state']").val(); String key = element.select("[name='key']").val(); String format = element.select("[name='format']").val(); // 利用會話保持,繼續模擬點選授權按鈕 提交form表單 HttpPost httpPostGetCode = new HttpPost(actionUrl); List<NameValuePair> nvps2 = new ArrayList<>(); nvps2.add(new BasicNameValuePair("app_id", app_id)); nvps2.add(new BasicNameValuePair("redirect_uri", redirect_uri)); nvps2.add(new BasicNameValuePair("state", state)); nvps2.add(new BasicNameValuePair("key", key)); nvps2.add(new BasicNameValuePair("format", format)); httpPostGetCode.setEntity(new UrlEncodedFormEntity(nvps2)); CloseableHttpResponse respGetCode = httpClient.execute(httpPostGetCode); try { HttpEntity entityGetCode = respGetCode.getEntity(); out.println("respAuth------------>>" + respGetCode.toString()); // 最終目的 獲取Location中的url中的某一值 Header location = respGetCode.getFirstHeader("Location"); out.println("location------------>>" + location.getValue()); EntityUtils.consume(entityGetCode); } finally { respGetCode.close(); } } finally { httpClient.close(); } } }