2010-02-12 19 views
37

मेरे पास एक सुंदर मूल सहायक वर्ग है जिसका उपयोग मैं अपने सभी एचटीपी प्राप्त/पोस्ट सामान करने के लिए कर रहा हूं। मैं org.apache.http लाइब्रेरी से HttpGet, HttpPost, और HttpClient का उपयोग कर रहा हूं। मेरी सभी चीजें HTTP पर ठीक काम करती हैं, लेकिन जैसे ही मैंने एचटीटीपीएस पर काम करने वाली सेवा का उपभोग करने की कोशिश की, मुझे अनुरोध निष्पादित करते समय क्लाइंटप्रोटोकॉल अपवाद प्राप्त होता है। अपवाद में एकमात्र संदेश है "सर्वर वैध HTTP प्रतिक्रिया के साथ प्रतिक्रिया करने में विफल रहा"।एंड्रॉइड में सुरक्षित HTTP पोस्ट

परीक्षण करने के लिए, मैंने अनुरोधकर्ता का उपयोग करके एक साधारण HTML फॉर्म और Fiddler2 का उपयोग कर ब्राउज़र से सटीक उसी पेलोड भेजा। मैंने अमान्य और खाली पेलोड भेज दिए हैं और यहां तक ​​कि शीर्ष पर और बिना हेडर के सभी को यह देखने के लिए भेजा है कि ऑब्जेक्ट अनुरोध के तरीके के बारे में कुछ गड़बड़ है या नहीं।

मैंने जो भी परीक्षण किया है, वह मुझे एक वैध 200 स्थिति HTTP प्रतिक्रिया देता है। सेवा सिर्फ मुझे त्रुटि का वर्णन करने वाली संरचना प्रदान करती है अगर मैं इसे अपेक्षा करता हूं जो कुछ भी अपेक्षा करता है।

क्या एचटीटीपीएस का उपयोग करने के लिए एचटीपीपोस्ट या एचटीपी क्लाइंट ऑब्जेक्ट में जोड़ने के लिए मुझे कुछ विशेष आवश्यकता है? क्या मुझे इसे एक अलग बंदरगाह का उपयोग करने के लिए स्पष्ट रूप से बताना है?

संपादित करें:

मैं वास्तव में https संचार के लिए गलत सॉकेट कारखाने पंजीकृत। यहाँ विधि अपडेट की गई है कि मैं सिर्फ मामले में किसी को सही सॉकेट कारखाने के साथ मेरी HttpClient वस्तु बनाने के लिए उपयोग भविष्य में इस तरह की समस्या खोजों है:

private HttpClient createHttpClient() 
{ 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); 
    HttpProtocolParams.setUseExpectContinue(params, true); 

    SchemeRegistry schReg = new SchemeRegistry(); 
    schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); 
    ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); 

    return new DefaultHttpClient(conMgr, params); 
} 
+0

हाय रिच, आपकी पोस्ट के लिए धन्यवाद, Google पर एंड्रॉइड पर https के बारे में यह एकमात्र चीज है। आपको यहां दिए गए कोड को लिखने के लिए कहां जानकारी मिली? इसके अलावा, क्या आप सेट संस्करण, वर्णसेट और उस पैरामीटर को कॉल करने का कारण बता सकते हैं? क्या वे डिफ़ॉल्ट रूप से सामान्य मान निर्दिष्ट नहीं करते हैं? एक और सवाल: आप org.apache.http.conn.ssl.SSLSocketFactory आयात कर रहे हैं, है ना? –

+0

को साफ़ करने के लिए धन्यवाद मुझे यकीन है कि यह एप्रेस पर प्रो एंड्रॉइड पुस्तक से आया है। पुस्तक बहुत अच्छी नहीं थी, लेकिन http संचार पर अध्याय व्यावहारिक डिजाइन के बारे में एक बड़ी चर्चा थी जब किसी ऐप को बहुत सी वेब कॉल करने की आवश्यकता होती है। – Rich

उत्तर

36

मुझे यकीन है कि तुम क्यों नहीं संभाल कर सकते हैं नहीं कर रहा हूँ HTTPS । मैंने अपने स्वयं के अनुप्रयोगों के लिए एक सहायक वर्ग लिखा और मैं किसी समस्या के बिना HTTPS को प्राप्त/पोस्ट करने में सक्षम हूं। मैं यहां कोड पोस्ट करूंगा और शायद आप देख सकते हैं कि मेरे कोड और आपके बीच अंतर है या नहीं।

import java.io.IOException; 
import java.io.InputStream; 
import java.io.UnsupportedEncodingException; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.net.URLConnection; 

import org.apache.http.HttpResponse; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.client.params.ClientPNames; 
import org.apache.http.client.params.CookiePolicy; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.params.BasicHttpParams; 
import org.apache.http.params.HttpConnectionParams; 
import org.apache.http.params.HttpParams; 
import org.apache.http.protocol.BasicHttpContext; 
import org.apache.http.protocol.HttpContext; 
import org.apache.http.util.EntityUtils; 
import org.json.JSONObject; 

import android.util.Log; 

public class HttpRequest{ 

    DefaultHttpClient httpClient; 
    HttpContext localContext; 
    private String ret; 

    HttpResponse response = null; 
    HttpPost httpPost = null; 
    HttpGet httpGet = null; 

    public HttpRequest(){ 
     HttpParams myParams = new BasicHttpParams(); 

     HttpConnectionParams.setConnectionTimeout(myParams, 10000); 
     HttpConnectionParams.setSoTimeout(myParams, 10000); 
     httpClient = new DefaultHttpClient(myParams);  
     localContext = new BasicHttpContext();  
    } 

    public void clearCookies() { 
     httpClient.getCookieStore().clear(); 
    } 

    public void abort() { 
     try { 
      if (httpClient != null) { 
       System.out.println("Abort."); 
       httpPost.abort(); 
      } 
     } catch (Exception e) { 
      System.out.println("Your App Name Here" + e); 
     } 
    } 

    public String sendPost(String url, String data) { 
     return sendPost(url, data, null); 
    } 

    public String sendJSONPost(String url, JSONObject data) { 
     return sendPost(url, data.toString(), "application/json"); 
    } 

    public String sendPost(String url, String data, String contentType) { 
     ret = null; 

     httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); 

     httpPost = new HttpPost(url); 
     response = null; 

     StringEntity tmp = null;   

     Log.d("Your App Name Here", "Setting httpPost headers"); 

     httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE"); 
     httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); 

     if (contentType != null) { 
      httpPost.setHeader("Content-Type", contentType); 
     } else { 
      httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
     } 

     try { 
      tmp = new StringEntity(data,"UTF-8"); 
     } catch (UnsupportedEncodingException e) { 
      Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e); 
     } 

     httpPost.setEntity(tmp); 

     Log.d("Your App Name Here", url + "?" + data); 

     try { 
      response = httpClient.execute(httpPost,localContext); 

      if (response != null) { 
       ret = EntityUtils.toString(response.getEntity()); 
      } 
     } catch (Exception e) { 
      Log.e("Your App Name Here", "HttpUtils: " + e); 
     } 

     Log.d("Your App Name Here", "Returning value:" + ret); 

     return ret; 
    } 

    public String sendGet(String url) { 
     httpGet = new HttpGet(url); 

     try { 
      response = httpClient.execute(httpGet); 
     } catch (Exception e) { 
      Log.e("Your App Name Here", e.getMessage()); 
     } 

     //int status = response.getStatusLine().getStatusCode(); 

     // we assume that the response body contains the error message 
     try { 
      ret = EntityUtils.toString(response.getEntity()); 
     } catch (IOException e) { 
      Log.e("Your App Name Here", e.getMessage()); 
     } 

     return ret; 
    } 

    public InputStream getHttpStream(String urlString) throws IOException { 
     InputStream in = null; 
     int response = -1; 

     URL url = new URL(urlString); 
     URLConnection conn = url.openConnection(); 

     if (!(conn instanceof HttpURLConnection))      
      throw new IOException("Not an HTTP connection"); 

     try{ 
      HttpURLConnection httpConn = (HttpURLConnection) conn; 
      httpConn.setAllowUserInteraction(false); 
      httpConn.setInstanceFollowRedirects(true); 
      httpConn.setRequestMethod("GET"); 
      httpConn.connect(); 

      response = httpConn.getResponseCode();     

      if (response == HttpURLConnection.HTTP_OK) { 
       in = httpConn.getInputStream();         
      }      
     } catch (Exception e) { 
      throw new IOException("Error connecting");    
     } // end try-catch 

     return in;  
    } 
} 
+0

इसके लिए धन्यवाद। मेरे पास एचटीपी क्लाइंट ऑब्जेक्ट (ऊपर पोस्ट किया गया) – Rich

+1

@MattC बनाने के लिए मेरे अपने कोड में एक बग था, मुझे नहीं लगता कि आप स्पष्ट रूप से 'एचटीपीएस' या पोर्ट 443 का उपयोग करने के लिए कहां परिभाषित कर रहे हैं ... क्या मुझे कुछ याद आ रहा है? यह एक सामान्य HTTP कनेक्शन की तरह दिखता है .. – Cody

+0

@DoctorOreo यह एक लंबा समय रहा है क्योंकि मैंने उस कोड को देखा है। मुझे याद है कि यह सही ढंग से HTTPS को संभालने में सक्षम है, लेकिन तब से ढांचा बहुत बदल गया है इसलिए मुझे वापस जाना और सत्यापित करना होगा। क्षमा करें मैं और मदद नहीं कर सका। – MattC

1

चूंकि कुछ विधियों को बहिष्कृत किया गया है, तो ऐसा नहीं होना चाहिए?

private DefaultHttpClient createHttpClient() { 
    HttpParams params = new BasicHttpParams(); 

    HttpConnectionParams.setConnectionTimeout(params, 10000); 
    HttpConnectionParams.setSoTimeout(params, 10000); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); 
    HttpProtocolParams.setUseExpectContinue(params, true); 

    SchemeRegistry schReg = new SchemeRegistry(); 
    schReg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); 
    schReg.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); 
    ClientConnectionManager conMgr = new PoolingClientConnectionManager(schReg); 

    return new DefaultHttpClient(conMgr, params); 
    } 

क्या मुझे कुछ और बदलना चाहिए, जैसे HttpVersion?

+1

हाँ। यह दो साल पहले पोस्ट किया गया था, लेकिन इन दिनों एंड्रॉइडHttpClient.newInstance अनिवार्य रूप से एक ही चीज़ है – Rich

+0

हाँ यह एंड्रॉइड पर काम नहीं करता है – JPM

संबंधित मुद्दे