1. 程式人生 > >HttpClient 重定向 302

HttpClient 重定向 302

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