Ich habe etwas Code für mein Android-Gerät geschrieben, um sich auf einer Website über https
einzuloggen und einige Daten aus den resultierenden Seiten zu analysieren. Eine HttpGet
passiert zuerst, um einige Informationen für die Anmeldung benötigt, dann eine HttpPost
, um den eigentlichen Login-Prozess zu tun.HttpPost funktioniert in Java-Projekt, nicht in Android
Der folgende Code funktioniert gut in einem Java-Projekt innerhalb von Eclipse, die die folgenden Jar-Dateien auf dem Build-Pfad hat: 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());
}
}
Der Server (die nicht unter meiner Kontrolle ist) gibt eine 302-Umleitung, wenn die Anmeldung erfolgreich war, und 200, wenn es fehlschlägt und wieder lädt die Login-Seite. Wenn ich mit den obigen Jar-Dateien laufe, bekomme ich die 302-Umleitung, aber wenn ich den exakt gleichen Code von einem Android-Projekt mit der Android-Jar-Datei 1.6 auf dem Build-Pfad laufe, bekomme ich die 200 Antwort vom Server. Ich bekomme die gleiche 200 Antwort, wenn ich den Code auf meinem 2.2 Gerät ausführe.
Meine Android-Anwendung hat Internet-Berechtigungen, und die HttpGet funktioniert gut. Ich gehe davon aus, dass das Problem in der Tatsache liegt, dass sich HttpPost (oder eine andere Klasse) in einer signifikanten Weise zwischen der Android Jar-Version und den neueren Apache-Versionen unterscheidet.
Ich habe versucht, die Apache-Bibliotheken zum Build-Pfad des Android-Projekts hinzufügen, aber aufgrund der doppelten Klassen bekomme ich Nachrichten wie: INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;'
im Protokoll. Ich habe auch versucht, eine MultipartEntity
anstelle der UrlEncodedFormEntity
zu verwenden, aber ich bekomme das gleiche Ergebnis 200.
Also, ich habe ein paar Fragen:
- Kann ich den Code zwingen, unter Android die neueren Apache-Bibliotheken anstelle der Android-Versionen zu verwenden?
- Wenn nicht, hat jemand irgendwelche Ideen, wie kann ich meinen Code ändern, so dass es mit dem Android Jar funktioniert?
- Gibt es andere, völlig andere Ansätze, um eine HttpPost in Android zu tun?
- Irgendwelche anderen Ideen?
Ich habe readalotofposts und code aber ich bin nicht weiter. Ich bin seit ein paar Tagen dran und weiß nicht, wie ich das Ding zur Arbeit bringen soll, also werde ich an dieser Stelle alles versuchen. Danke im Voraus.
gute Antwort. in Lebkuchen und später, HttpURLConnection ist der Weg zu gehen. Betrachte Apache HttpClient als veraltet. –