2010-11-19 18 views
5

में मैंने अपने एंड्रॉइड डिवाइस के लिए https पर किसी वेबसाइट पर लॉगिन करने के लिए कुछ कोड लिखा है और परिणामी पृष्ठों से कुछ डेटा पार्स किया है। लॉगिन के लिए कुछ जानकारी प्राप्त करने के लिए पहले HttpGet वास्तविक लॉगिन प्रक्रिया करने के लिए HttpPost प्राप्त होता है। 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 अगर यह विफल रहता है और फिर से लोड प्रवेश पृष्ठ। उपरोक्त जार फ़ाइलों के साथ चलाते समय मुझे 302 रीडायरेक्ट मिलता है, हालांकि अगर मैं एंड्रॉइड प्रोजेक्ट से सटीक कोड चलाता हूं तो बिल्ड पथ पर 1.6 एंड्रॉइड जार फ़ाइल के साथ मुझे सर्वर से 200 प्रतिक्रिया मिलती है। मेरे 2.2 डिवाइस पर कोड चलाते समय मुझे 200 प्रतिक्रिया मिलती है।

मेरे एंड्रॉइड एप्लिकेशन में इंटरनेट अनुमतियां हैं, और एचटीपीजीट ठीक काम करता है। मुझे लगता है कि समस्या इस तथ्य में निहित है कि एंड्रॉइड जार संस्करण और नए अपाचे संस्करणों के बीच कुछ महत्वपूर्ण तरीके से एचटीपीपोस्ट (या कुछ अन्य वर्ग) अलग है।

मैंने एंड्रॉइड प्रोजेक्ट के निर्माण पथ में अपाचे लाइब्रेरी जोड़ने का प्रयास किया है, लेकिन डुप्लिकेट कक्षाओं के कारण मुझे लॉग में INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;' संदेश मिलते हैं। मैंने UrlEncodedFormEntity के बजाय MultipartEntity का उपयोग करने का भी प्रयास किया है, लेकिन मुझे 200 परिणाम मिलते हैं।

तो, मैं कुछ प्रश्न हैं:
- मैं Android संस्करण वरीयता में नए अपाचे पुस्तकालयों का उपयोग करने के लिए कोड एंड्रॉयड के तहत चल मजबूर कर सकते हैं?
- यदि नहीं, तो क्या किसी के पास कोई विचार है कि मैं अपना कोड कैसे बदल सकता हूं ताकि यह एंड्रॉइड जार के साथ काम कर सके?
- एंड्रॉइड में एचटीपीपोस्ट करने के लिए कोई अन्य, पूरी तरह से अलग दृष्टिकोण हैं?
- कोई अन्य विचार?

मैं readalotofposts और code है लेकिन मैं कहीं भी नहीं मिल रहा है। मैं इस पर कुछ दिनों तक फंस गया हूं और मुझे नुकसान हुआ है कि काम को कैसे काम करना है, इसलिए मैं इस बिंदु पर कुछ भी कोशिश करूंगा। अग्रिम में धन्यवाद।

उत्तर

6

एंड्रॉयड के लिए जा रहा है ... मैं अब उम्मीद प्रतिक्रिया देने के लिए HttpClient मार्ग हो रही पर छोड़ दिया है उस के साथ समस्या नहीं थी एंड्रॉइड पर चलने पर सर्वर से। इसके बजाय मैं HttpsURLConnection का उपयोग करने के लिए उपरोक्त doPost विधि को फिर से लिखता हूं। उम्मीद में नया (कामकाजी) संस्करण यहां दिया गया है कि यह किसी के लिए उपयोगी है।

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

अच्छा जवाब। जिंजरब्रेड में और बाद में, HttpURLConnection जाने का रास्ता है। Apache HttpClient बहिष्कृत पर विचार करें। –

0

क्या यह संभव है कि यह वेबसाइट उपयोगकर्ता-एजेंट पहचान करे और वास्तव में अलग-अलग परिणाम देता है क्योंकि यह एंड्रॉइड है? यह देखते हुए कि 200 सफलता का तात्पर्य है, इसे 200 के बजाय 302 क्यों देना चाहिए? क्या आपने परिणाम को मुद्रित किया है जो आपको 200 लौटाता है, और क्या यह कोई अतिरिक्त जानकारी देता है?

+0

200 परिणाम होगा से बचने के लिए बस उपयोगकर्ता प्रवेश पृष्ठ फिर से है, के साथ कोई त्रुटि संदेश या अन्य जानकारी, जो सामान्य रूप से गलत लॉगिन के साथ होती है। मैं उपयोगकर्ता-एजेंट को हेडर में स्पष्ट रूप से सेट कर रहा हूं, और यह वही सेट है जिसे कोड कहा जाता है। मैं अपने एंड्रॉइड फोन पर ब्राउजर से साइट पर ठीक से लॉगिन कर सकता हूं, जिसका मतलब है कि यह एंड्रॉइड के तथ्य के आधार पर अवरुद्ध नहीं है। –

0

RedirectHandler की जाँच करें, डिफ़ॉल्ट ओवरराइड और इसमें कुछ प्रवेश करते हैं, मैं जब

+0

मैं रीडायरेक्ट कोड (जिसे मैंने ऊपर शामिल नहीं किया था) से काफी खुश हूं, समस्या यह है कि मैं अब तक भी नहीं प्राप्त कर रहा हूं। चूंकि सर्वर ग्रहण से वापस आने वाले 302 की बजाय एंड्रॉइड से 200 कोड लौटा रहा है, इसलिए मैं उस हिस्से तक नहीं पहुंच रहा हूं जहां मुझे रीडायरेक्ट को संभालने की आवश्यकता है। –

+0

हम, क्या यह उपयोगकर्ता एजेंट समस्या हो सकता है? – dacwe

+0

उपयोगकर्ता एजेंट उपरोक्त कोड में सेट है, और यह उसी मान पर सेट है कि यह एंड्रॉइड के भीतर या शुद्ध जावा के रूप में चलाया गया है या नहीं। मैंने एंड्रॉइड उपयोगकर्ता एजेंट, एक एफएफ/विंडोज़ और कुछ कस्टम लोगों की कोशिश की है। वे सभी एक ही व्यवहार देते हैं। –

1

टकराव httpclient

httplib

के लिए इस जार का उपयोग करें और इस पोस्ट भी बहुत उपयोगी

stack overflow post

+0

किसी के लिए भविष्य के उपयोग के लिए मदद करेगा ... –