HttpPost работает в проекте Java, а не в Android - PullRequest
5 голосов
/ 19 ноября 2010

Я написал некоторый код для моего устройства Android, чтобы войти на веб-сайт через https и проанализировать некоторые данные на полученных страницах. HttpGet происходит сначала, чтобы получить некоторую информацию, необходимую для входа в систему, а затем HttpPost, чтобы выполнить фактический процесс входа в систему.

Приведенный ниже код прекрасно работает в Java-проекте в Eclipse, в котором есть следующие Jar-файлы в пути сборки: httpcore-4.1-beta2.jar, httpclient-4.1-alpha2.jar, httpmime-4.1-alpha2.jar, commons-logging-1.1.1.jar.

public static MyBean gatherData(String username, String password) {
    MyBean myBean = new MyBean();
    try {
        HttpResponse response = doHttpGet(URL_PAGE_LOGIN, null, null);
        System.out.println("Got login page");
        String content = EntityUtils.toString(response.getEntity());
        String token = ContentParser.getToken(content);
        String cookie = getCookie(response);
        System.out.println("Performing login");
        System.out.println("token = "+token +" || cookie = "+cookie);
        response = doLoginPost(username,password,cookie, token);
        int respCode = response.getStatusLine().getStatusCode();
        if (respCode != 302) {
            System.out.println("ERROR: not a 302 redirect!: code is \""+ respCode+"\"");
            if (respCode == 200) {
                System.out.println(getHeaders(response));
                System.out.println(EntityUtils.toString(response.getEntity()).substring(0, 500));
            }
        } else {
            System.out.println("Logged in OK, loading account home");
            // redirect handler and rest of parse removed
        }
    }catch (Exception e) {
        System.out.println("ERROR in gatherdata: "+e.toString());
        e.printStackTrace();
    }
    return myBean;
}
private static HttpResponse doHttpGet(String url, String cookie, String referrer) {
    try {
        HttpClient client = new DefaultHttpClient();
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
        HttpGet httpGet = new HttpGet(url);
        httpGet.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        httpGet.setHeader(HEADER_USER_AGENT,HEADER_USER_AGENT_VALUE);
        if (referrer != null && !referrer.equals("")) httpGet.setHeader(HEADER_REFERER,referrer);
        if (cookie != null && !cookie.equals("")) httpGet.setHeader(HEADER_COOKIE,cookie);
        return client.execute(httpGet);
    } catch (Exception e) {
        e.printStackTrace();
        throw new ConnectException("Failed to read content from response");
    }
}
private static HttpResponse doLoginPost(String username, String password, String cookie, String token) throws ClientProtocolException, IOException {
    try {
        HttpClient client = new DefaultHttpClient();
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
        HttpPost post = new HttpPost(URL_LOGIN_SUBMIT);
        post.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        post.setHeader(HEADER_USER_AGENT,HEADER_USER_AGENT_VALUE);
        post.setHeader(HEADER_REFERER, URL_PAGE_LOGIN);
        post.setHeader(HEADER_COOKIE, cookie);
        post.setHeader("Content-Type","application/x-www-form-urlencoded");
        List<NameValuePair> formParams = new ArrayList<NameValuePair>();
        formParams.add(new BasicNameValuePair("org.apache.struts.taglib.html.TOKEN", token));
        formParams.add(new BasicNameValuePair("showLogin", "true"));
        formParams.add(new BasicNameValuePair("upgrade", ""));
        formParams.add(new BasicNameValuePair("username", username));
        formParams.add(new BasicNameValuePair("password", password));
        formParams.add(new BasicNameValuePair("submit", "Secure+Log+in"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams,HTTP.UTF_8);
        post.setEntity(entity);
        return client.execute(post);
    } catch (Exception e) {
        e.printStackTrace();
        throw new ConnectException("ERROR in doLoginPost(): "+e.getMessage());
    }
}

Сервер (который не находится под моим контролем) возвращает перенаправление 302 при успешном входе в систему и 200 при сбое и повторную загрузку страницы входа. При запуске с указанными выше файлами Jar я получаю перенаправление 302, однако, если я запускаю точно такой же код из проекта Android с файлом Jar Android 1.6 в пути сборки, я получаю ответ 200 от сервера. Я получаю тот же ответ 200 при запуске кода на моем устройстве 2.2.

У моего андроид-приложения есть интернет-разрешения, и HttpGet работает нормально. Я предполагаю, что проблема заключается в том факте, что HttpPost (или какой-то другой класс) существенно отличается между версией Android Jar и более новыми версиями Apache.

Я пытался добавить библиотеки Apache в путь сборки проекта Android, но из-за дублирующихся классов я получаю сообщения типа: INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;' в журнале. Я также пытался использовать MultipartEntity вместо UrlEncodedFormEntity, но получаю тот же результат 200.

Итак, у меня есть несколько вопросов:
- Могу ли я заставить код, работающий под Android, использовать более новые библиотеки Apache по сравнению с версиями Android?
- Если нет, у кого-нибудь есть идеи, как я могу изменить свой код, чтобы он работал с Android Jar?
- Есть ли другие, совершенно разные подходы к созданию HttpPost в Android?
- Есть еще идеи?

Я прочитал a лот из сообщений и код , но Я никуда не денусь. Я застрял на этом в течение нескольких дней, и я не знаю, как заставить это работать, так что я попробую что-нибудь на этом этапе. Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 04 января 2011

Я отказался от получения маршрута HttpClient, чтобы дать ожидаемый ответ от сервера при запуске на Android. Вместо этого я переписал doPost метод выше, чтобы использовать HttpsURLConnection вместо этого. Вот новая (рабочая) версия в надежде, что она кому-нибудь пригодится.

private static LoginBean altPost(String username, String password, String cookie, String token){
    LoginBean loginBean = new LoginBean();
    HttpsURLConnection urlc = null;
    OutputStreamWriter out = null;
    DataOutputStream dataout = null;
    BufferedReader in = null;
    try {
        URL url = new URL(URL_LOGIN_SUBMIT);
        urlc = (HttpsURLConnection) url.openConnection();
        urlc.setRequestMethod("POST");
        urlc.setDoOutput(true);
        urlc.setDoInput(true);
        urlc.setUseCaches(false);
        urlc.setAllowUserInteraction(false);
        urlc.setRequestProperty(HEADER_USER_AGENT, HEADER_USER_AGENT_VALUE_FF);
        urlc.setRequestProperty("Cookie", cookie);
        urlc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        String output = "org.apache.struts.taglib.html.TOKEN="+ URLEncoder.encode(token, HTTP.UTF_8)
                +"&showLogin=true&upgrade=&username="+ URLEncoder.encode(username, HTTP.UTF_8)
                +"&password="+ URLEncoder.encode(password, HTTP.UTF_8)+"&submit="
                +URLEncoder.encode("Secure+Log+in", HTTP.UTF_8);
        dataout = new DataOutputStream(urlc.getOutputStream());
        // perform POST operation
        dataout.writeBytes(output);
        // get response info
        loginBean.setResponseCode(urlc.getResponseCode());
        // get required headers
        String headerName = null;
        StringBuffer newCookie = new StringBuffer(100);
        String redirectLocation = "";
        for (int i=1; (headerName = urlc.getHeaderField(i)) != null;i++) {
            if (headerName.indexOf(COOKIE_VALUE_SESSION) > -1) {
                if (newCookie.length() > 0) {newCookie.append("; ");}
                newCookie.append(headerName);
            }
            if (headerName.indexOf(COOKIE_VALUE_AUTH) > -1) {
                if (newCookie.length() > 0) {newCookie.append("; ");}
                newCookie.append(headerName);
            }
            if (headerName.indexOf("https://") > -1) {
                redirectLocation = headerName;
            }
        }
        loginBean.setCookie(newCookie.toString());
        loginBean.setRedirectUrl(redirectLocation);

        in = new BufferedReader(new InputStreamReader(urlc.getInputStream()),8096);
        String response;
        // write html to System.out for debug
        while ((response = in.readLine()) != null) {
            System.out.println(response);
        }
        in.close();
    } catch (ProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return loginBean;
}

Я до сих пор не понимаю, почему способ HttpClient не работал должным образом.

1 голос
/ 05 октября 2012

чтобы избежать коллизий, используйте этот jar для httpclient

httplib

, и этот пост также будет очень полезен

переполнение стекапочта

0 голосов
/ 19 ноября 2010

Проверьте RedirectHandler, переопределите стандартный и выполните вход в него, у меня были проблемы с этим при переходе на Android ...

0 голосов
/ 19 ноября 2010

Возможно ли, что этот сайт обнаруживает пользовательский агент и на самом деле возвращает разные результаты, потому что это Android?Учитывая, что 200 означает успех, почему он должен давать 302 вместо 200?Распечатали ли вы результат, который вы получите, когда он возвращает 200, и дает ли он дополнительную информацию?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...