使用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();
}
}
}