我为Android设备编写了一些代码,以登录到网站https
并从结果页面中解析出一些数据。一个HttpGet
发生抢先拿到需要登陆一些信息,那么HttpPost
做实际的登录过程。
下面在Eclipse中的Java项目,具有构建路径上的下列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重定向,但是,如果我在构建路径中使用1.6 Android Jar文件从Android项目运行完全相同的代码,则会从服务器获得200响应。在我的2.2设备上运行代码时,我得到相同的200响应。
我的Android应用程序具有Internet权限,并且HttpGet可以正常工作。我假设问题出在以下事实:在Android Jar版本和较新的Apache版本之间,HttpPost(或某些其他类)在某些方面存在显着差异。
我曾尝试将Apache库添加到Android项目的构建路径中,但是由于重复的类,我INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;'
在日志中收到如下消息:我也尝试过使用MultipartEntity
而不是,UrlEncodedFormEntity
但是得到了相同的200结果。
因此,我有几个问题:
- 我是否可以强制在android下运行的代码优先于Android版本使用更新的Apache库?
-如果没有,是否有人有任何想法如何更改代码以使其与Android Jar兼容?
-在Android中是否还有其他完全不同的方法来执行HttpPost?
-还有其他想法吗?
我读 一个 很大 的 职位及代码,但我没有得到任何地方。我已经坚持了几天,但我不知该如何使它正常工作,因此我将尽一切努力。提前致谢。
我现在已经放弃了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
方式无法正常工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句