HttpPost работает в Java-проекте, а не в Android

Я написал код для моего устройства 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 с 1,6 Android Jar-файлом на пути сборки, я получаю ответ 200 с сервера. Я получаю тот же ответ 200 при запуске кода на моем устройстве 2.2.

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

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

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

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

Теперь я отказался от получения маршрута 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 не работал должным образом.

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

HTTPLIB

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

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

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

Проверьте RedirectHandler, переопределите значение по умолчанию и выполните некоторые записи в нем, у меня были проблемы с этим при переходе на Android …