He escrito un código para mi dispositivo Android para iniciar sesión en un sitio web más https
y analizar algunos datos de las páginas resultantes. Un HttpGet
pasa primero para obtener información necesaria para iniciar sesión, luego un HttpPost
para realizar el proceso de inicio de sesión real.HttpPost funciona en el proyecto Java, no en Android
El código siguiente funciona muy bien en un proyecto Java en Eclipse que tiene los siguientes archivos Jar en la trayectoria de la estructura: 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());
}
}
El servidor (que no está bajo mi control) devuelve una redirección 302 cuando la entrada se ha realizado correctamente, y 200 si se produce un error y vuelve a cargar la página de inicio de sesión. Cuando se ejecutan con los archivos Jar anteriores, obtengo la redirección 302, sin embargo, si ejecuto exactamente el mismo código de un proyecto de Android con el archivo 1.6 Android Jar en la ruta de compilación recibo la respuesta 200 del servidor. Obtengo la misma respuesta 200 cuando ejecuto el código en mi dispositivo 2.2.
Mi aplicación para Android tiene permisos de internet y el HttpGet funciona bien. Asumo que el problema radica en el hecho de que HttpPost (o alguna otra clase) es diferente de alguna manera significativa entre la versión Android Jar y las versiones más nuevas de Apache.
He intentado agregar las bibliotecas de Apache a la ruta de compilación del proyecto de Android, pero debido a las clases duplicadas recibo mensajes como: INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;'
en el registro. También intenté usar un MultipartEntity
en lugar del UrlEncodedFormEntity
pero obtengo el mismo resultado de 200.
Por lo tanto, tengo algunas preguntas:
- ¿Puedo forzar el código que se ejecuta en Android para utilizar las bibliotecas Apache más nuevas en lugar de las versiones de Android?
- Si no, ¿alguien tiene alguna idea de cómo puedo alterar mi código para que funcione con Android Jar?
- ¿Hay algún otro enfoque totalmente diferente para hacer un HttpPost en Android?
- ¿Alguna otra idea?
he readalotofposts y code pero no voy a llegar a ninguna parte. Estuve atascado en esto por un par de días y no sé cómo hacer que la cosa funcione, así que intentaré cualquier cosa en este momento. Gracias por adelantado.
buena respuesta. en Gingerbread y más tarde, HttpURLConnection es el camino a seguir. considere que Apache HttpClient está en desuso. –