2010-11-19 15 views
5

私はAndroidデバイス用のコードを書いてhttps以上のWebサイトにログインし、結果のページからデータを解析します。 HttpGetは、まずログインに必要な情報を取得してから、実際のログインプロセスを行うためにHttpPostを取得します。HttpPostはAndroidプロジェクトではなくJavaプロジェクトで動作します

次のコードは、ビルド・パスに次のJARファイルを持ってEclipse内のJavaプロジェクトで素晴らしい作品:httpcore-4.1-beta2.jarhttpclient-4.1-alpha2.jarhttpmime-4.1-alpha2.jarcommons-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アプリケーションにはインターネットアクセス権があり、HttpGetは正常に動作します。私は問題がHttpPost(または他のいくつかのクラス)がAndroid Jarバージョンとより新しいApacheバージョンの間でいくつかの重要な方法で異なっているという事実にあると仮定しています。

私はAndroidプロジェクトのビルドパスにApacheライブラリを追加しようとしましたが、重複したクラスのためにログにINFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;'というメッセージが表示されます。私もUrlEncodedFormEntityの代わりにMultipartEntityを使ってみましたが、私は同じ200の結果を得ます。

私はいくつかの質問があります:
- アンドロイドで実行されているコードで、Androidのバージョンより新しいApacheライブラリを使用するよう強制できますか?
- そうでない場合は、Android Jarで動作するようにコードを変更する方法はありますか?
- AndroidでHttpPostを実行するための方法はまったく異なりますか?
- その他のアイデアですか?

私はreadalotofpostscodeをしましたが、私はどこにも届きません。私は数日間これに固執していたし、私は仕事をする方法を失っているので、私はこの時点で何かを試してみます。前もって感謝します。

答えて

6

私は今、期待される応答を与えるために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の方法が正しく機能しなかった理由はまだ分かりません。衝突を避けるために

+1

良い答えです。 Gingerbreadでは、後でHttpURLConnectionを使用する方法があります。推奨されないApache HttpClientを検討してください。 –

0

Androidエージェントであるため、このウェブサイトでユーザーエージェントの検出が行われ、結果が異なる可能性がありますか? 200が成功を意味するとすれば、なぜそれが200の代わりに302を与えなければならないのですか?あなたが200を返したときに得た結果を印刷しましたか?それに追加の情報はありますか?

+0

非常に有用であろうため、このjarファイルを使用しますエラーメッセージやその他の情報はありません。これは、通常、誤ったログインで発生します。私はヘッダーで明示的にユーザーエージェントを設定しています。コードが呼び出されたときと同じ方法で設定されています。私はアンドロイドの事実に基づいてブロックされていないことを意味し、私のアンドロイドの携帯電話のブラウザからOKのサイトにログインすることができます。 –

0

、RedirectHandlerをチェックデフォルトのものをオーバーライドして、Androidのに行くとき、私はそれで問題を抱えていた、それにいくつかのロギングを行う...

+0

リダイレクトコード(これは私が上記には含まれていませんでした)にはかなり満足していますが、問題は私がそれほど遠慮していないことです。サーバーはEclipseから返された302ではなく、Androidから200コードを返すので、私はリダイレクトを処理する必要がある部分には行きません。 –

+0

Hum、それはユーザーエージェントの問題でしょうか? – dacwe

+0

ユーザエージェントは上記のコードで設定され、Android内で実行されようと純粋なJavaで実行されても同じ値に設定されています。私はアンドロイドのユーザーエージェント、FF/Windowsとカスタムのものを試しました。彼らはすべて同じ行動をします。 –

1

はHTTPClientを

httplib

と、この記事でも200結果がで、再び単にユーザーのログインページで

stack overflow post

+0

将来の使用のために誰かのために役立つだろう... –

関連する問題