我已經爲我的Android設備編寫了一些代碼,通過https
登錄到網站,並從結果頁面中解析出一些數據。一個HttpGet
首先發生登錄需要一些信息,然後HttpPost
做實際的登錄過程。 httpcore-4.1-beta2.jar
,httpclient-4.1-alpha2.jar
,httpmime-4.1-alpha2.jar
,commons-logging-1.1.1.jar
:下面HttpPost在Java項目中工作,而不在Android中
中的代碼在Eclipse中的Java項目,具有構建路徑上的下列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重定向,但是如果我在構建路徑上使用1.6 Android Jar文件從Android項目運行完全相同的代碼,則會從服務器獲得200響應。在2.2設備上運行代碼時,我得到相同的200響應。
我的android應用程序具有Internet權限,並且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協同工作?
- 有沒有其他的,完全不同的方法來做Android的HttpPost?
- 有沒有其他想法?
我已經readalotofposts和code但我沒有在任何地方獲得。我一直堅持這一兩天,我不知道如何讓事情發揮作用,所以我會在這一點上嘗試任何事情。提前致謝。
很好的答案。在薑餅和後來,HttpURLConnection是要走的路。不推薦使用Apache HttpClient。 – 2011-03-10 19:26:47