2012-04-12 25 views
114

मैं वेब सेवा से कनेक्ट करने के लिए HTTPURLConnection का उपयोग कर रहा हूं। मुझे पता है कि HTTPURLConnection का उपयोग कैसे करें, लेकिन मैं समझना चाहता हूं कि यह कैसे काम करता है। असल में, मैं निम्नलिखित जानना चाहता हूं:क्या आप HttpURLConnection कनेक्शन प्रक्रिया को समझा सकते हैं?

  • किस बिंदु पर HTTPURLConnection दिए गए यूआरएल से कनेक्शन स्थापित करने का प्रयास करता है?
  • मुझे किस बिंदु पर पता चलेगा कि मैं सफलतापूर्वक कनेक्शन स्थापित करने में सक्षम था?
  • एक कनेक्शन स्थापित कर रहे हैं और एक चरण/विधि कॉल में किए गए वास्तविक अनुरोध को भेज रहे हैं? यह क्या तरीका है?
  • क्या आप लेमन के कार्यकाल में getOutputStream और getInputStream के फ़ंक्शन को समझा सकते हैं? मुझे पता है कि जब मैं जिस सर्वर से कनेक्ट करने का प्रयास कर रहा हूं वह नीचे है, तो मुझे ExceptiongetOutputStream पर मिलता है। क्या इसका मतलब यह है कि HTTPURLConnection केवल getOutputStream का आह्वान करते समय कनेक्शन स्थापित करना शुरू कर देगा? getInputStream के बारे में कैसे? चूंकि मैं केवल getInputStream पर प्रतिक्रिया प्राप्त करने में सक्षम हूं, तो क्या इसका मतलब यह है कि मैंने अभी तक getOutputStream पर कोई अनुरोध नहीं भेजा है, लेकिन बस एक कनेक्शन स्थापित करता है? HttpURLConnection जब मैं getInputStream का आह्वान करता हूं तो प्रतिक्रिया के लिए अनुरोध करने के लिए सर्वर पर वापस जाएं?
  • क्या मैं यह कहने में सही हूं कि openConnection बस एक नया कनेक्शन ऑब्जेक्ट बनाता है लेकिन अभी तक कोई कनेक्शन स्थापित नहीं करता है?
  • मैं ओवरहेड पढ़ने और ओवरहेड को कैसे जोड़ सकता हूं?
+0

मैं करूंगा सुझाव है पढ़ [इस अतः चर्चा] (https://stackoverflow.com/questions/2793150/using-java-net-urlconnection-to-fire-and-handle-http - सुधार) बेहतर समझ के लिए। यह भी देखें [यह ब्लॉग] (http://opensourceforgeeks.blogspot.in/2017/04/using-httpurlconnection-in-android.html)। –

उत्तर

159
String message = URLEncoder.encode("my message", "UTF-8"); 

try { 
    // instantiate the URL object with the target URL of the resource to 
    // request 
    URL url = new URL("http://www.example.com/comment"); 

    // instantiate the HttpURLConnection with the URL object - A new 
    // connection is opened every time by calling the openConnection 
    // method of the protocol handler for this URL. 
    // 1. This is the point where the connection is opened. 
    HttpURLConnection connection = (HttpURLConnection) url 
      .openConnection(); 
    // set connection output to true 
    connection.setDoOutput(true); 
    // instead of a GET, we're going to send using method="POST" 
    connection.setRequestMethod("POST"); 

    // instantiate OutputStreamWriter using the output stream, returned 
    // from getOutputStream, that writes to this connection. 
    // 2. This is the point where you'll know if the connection was 
    // successfully established. If an I/O error occurs while creating 
    // the output stream, you'll see an IOException. 
    OutputStreamWriter writer = new OutputStreamWriter(
      connection.getOutputStream()); 

    // write data to the connection. This is data that you are sending 
    // to the server 
    // 3. No. Sending the data is conducted here. We established the 
    // connection with getOutputStream 
    writer.write("message=" + message); 

    // Closes this output stream and releases any system resources 
    // associated with this stream. At this point, we've sent all the 
    // data. Only the outputStream is closed at this point, not the 
    // actual connection 
    writer.close(); 
    // if there is a response code AND that response code is 200 OK, do 
    // stuff in the first if block 
    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { 
     // OK 

     // otherwise, if any other status code is returned, or no status 
     // code is returned, do stuff in the else block 
    } else { 
     // Server returned HTTP error code. 
    } 
} catch (MalformedURLException e) { 
    // ... 
} catch (IOException e) { 
    // ... 
} 

पहले 3 जवाब अपने प्रश्नों के ऊपर के उदाहरण HTTP POST में इनलाइन टिप्पणी के रूप में सूचीबद्ध किया गया है, प्रत्येक विधि के बगल में,।

getOutputStream से:

एक निर्गम धारा है कि इस संबंध के लिए लिखते हैं देता है।

असल में, मुझे लगता है कि आपको यह कैसे काम करता है इसकी अच्छी समझ है, इसलिए मुझे केवल आम आदमी के नियमों में दोहराएं। getOutputStream मूल रूप से सर्वर पर डेटा लिखने के इरादे से कनेक्शन स्ट्रीम खोलता है। उपर्युक्त कोड उदाहरण में "संदेश" एक टिप्पणी हो सकती है कि हम उस सर्वर पर भेज रहे हैं जो किसी पोस्ट पर छोड़ी गई टिप्पणी का प्रतिनिधित्व करता है। जब आप getOutputStream देखते हैं, तो आप लिखने के लिए कनेक्शन स्ट्रीम खोल रहे हैं, लेकिन जब तक आप writer.write("message=" + message); पर कॉल नहीं करते हैं, तब तक आप वास्तव में कोई डेटा नहीं लिखते हैं।

getInputStream() से:

एक इनपुट धारा है कि इस खुले कनेक्शन से पढ़ता है देता है। एक सॉकेटटाइमआउट एक्सेप्शन को लौटाया जा सकता है जब लौटा इनपुट स्ट्रीम से पढ़ा जा सकता है यदि पढ़ने के लिए डेटा समाप्त होने से पहले रीड टाइमआउट समाप्त हो जाता है।

getInputStream विपरीत है। getOutputStream की तरह, यह कनेक्शन स्ट्रीम भी खुलता है, लेकिन इसका उद्देश्य सर्वर से डेटा पढ़ना है, इसे लिखना नहीं है। यदि कनेक्शन या स्ट्रीम-ओपनिंग विफल हो जाती है, तो आपको SocketTimeoutException दिखाई देगा।

getInputStream के बारे में कैसे? चूंकि मैं getInputStream पर प्रतिक्रिया प्राप्त करने में सक्षम हूं, तो क्या इसका मतलब यह है कि मैंने getOutputStream पर अभी तक कोई अनुरोध नहीं भेजा है, लेकिन बस एक कनेक्शन स्थापित करता है?

ध्यान रखें कि डेटा एक अनुरोध भेजने और भेजने दो अलग संचालन कर रहे हैं। जब आप प्राप्त करते हैं तो आउटपुट आउटस्ट्रीम या getInputStream url.openConnection(), आप कनेक्शन स्थापित करने के लिए सर्वर से अनुरोध भेजते हैं। एक हैंडशेक होता है जो तब होता है जब सर्वर आपको एक पावती भेजता है कि कनेक्शन स्थापित है। यह तब उस समय है जब आप डेटा भेजने या प्राप्त करने के लिए तैयार हैं। इस प्रकार, आपको GetOutputStream को पर एक कनेक्शन स्थापित करने की आवश्यकता नहीं है एक स्ट्रीम खोलें, जब तक कि अनुरोध करने का आपका उद्देश्य डेटा भेजना न हो।

आम आदमी के नियमों में, getInputStream अनुरोध करना आपके मित्र के घर पर एक फोन कॉल करने के बराबर है "अरे, क्या यह ठीक है अगर मैं आ गया और उपर की जोड़ी उधार लेता हूं?" और आपका दोस्त यह कहकर हैंडशेक स्थापित करता है, "ज़रूर! आओ और इसे प्राप्त करें"। फिर, उस बिंदु पर, कनेक्शन बनाया जाता है, आप अपने दोस्त के घर जाते हैं, दरवाजे पर दस्तक देते हैं, उपाध्यक्षों का अनुरोध करते हैं, और अपने घर वापस चले जाते हैं।

getOutputStream के लिए एक समान उदाहरण का उपयोग करने से आपके मित्र को फोन करने और कहने में शामिल होगा "अरे, मेरे पास वह पैसा है जो मैं आपको दे सकता हूं, क्या मैं इसे आपको भेज सकता हूं"? आपके दोस्त, पैसे और बीमार की जरूरत है कि आप इसे इतने लंबे समय तक रखते हैं, "निश्चित रूप से, आप पर सस्ते बेस्टर्ड पर आते हैं"। तो आप अपने दोस्त के घर जाते हैं और उसे "पोस्ट" पैसे देते हैं। फिर वह आपको बाहर निकाल देता है और आप अपने घर वापस चले जाते हैं।

अब, आम आदमी के उदाहरण के साथ जारी रखते हुए, आइए कुछ अपवाद देखें। अगर आप अपने दोस्त को बुलाते हैं और वह घर नहीं था, तो यह 500 त्रुटि हो सकती है। यदि आपने डिस्कनेक्ट किए गए नंबर संदेश को बुलाया और मिला क्योंकि आपका मित्र हर समय पैसे उधार ले रहा है, तो यह 404 पृष्ठ नहीं मिला है। यदि आपका फोन मर चुका है क्योंकि आपने बिल का भुगतान नहीं किया है, तो यह एक IOException हो सकता है। (नोट: यह खंड 100% सही नहीं किया जा सकता कि आप कौन से आम आदमी की दृष्टि में हो रहा है की एक सामान्य विचार दे करने का इरादा है।।)

प्रश्न # 5:

हाँ, आपको लगता है कि सही हैं openConnection बस एक नया कनेक्शन ऑब्जेक्ट बनाता है लेकिन इसे स्थापित नहीं करता है। जब आप getInputStream या getOutputStream को कॉल करते हैं तो कनेक्शन स्थापित होता है।

openConnection एक नया कनेक्शन ऑब्जेक्ट बनाता है। URL.openConnection javadocs से:

इस URL के लिए प्रोटोकॉल हैंडलर की openConnection विधि को कॉल करके हर बार एक नया कनेक्शन खोला जाता है।

कनेक्शन स्थापित हो जाने के लिए जब आप openConnection कहते हैं, और InputStream, OutputStream, या दोनों, कहा जाता है जब आप उन्हें का दृष्टांत।

प्रश्न # 6:

भूमि के ऊपर मापने के लिए, मैं आम तौर पर कुछ बहुत ही सरल समय कोड पूरे कनेक्शन ब्लॉक के चारों ओर, लपेट इतना की तरह:

long start = System.currentTimeMillis(); 
log.info("Time so far = " + new Long(System.currentTimeMillis() - start)); 

// run the above example code here 
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start)); 

मुझे यकीन है कि वहाँ और अधिक कर रहे हैं हूँ अनुरोध समय और ओवरहेड को मापने के लिए उन्नत विधियां, लेकिन यह आमतौर पर मेरी आवश्यकताओं के लिए पर्याप्त है।

कनेक्शन बंद करने की जानकारी के लिए, जिसे आपने नहीं पूछा था, In Java when does a URL connection close? देखें।

+0

हाय। धन्यवाद!!! यह वास्तव में एक विस्तृत स्पष्टीकरण था और मैं वास्तव में आपके उत्तर की सराहना करता हूं। अगर मैं आपके उत्तर को सही ढंग से समझता हूं, तो दोनों आउटपुटस्ट्रीम प्राप्त करें और getInputStream कनेक्शन स्थापित करता है यदि अभी तक कोई कनेक्शन स्थापित नहीं हुआ है। अगर मैं getOutputStream को कॉल करता हूं, तो getInputStream को कॉल करें, आंतरिक रूप से, HTTPURL कनेक्शन अब getInputStream पर कनेक्शन को पुन: स्थापित नहीं करेगा क्योंकि मैं इसे GetOutStream पर स्थापित करने में सक्षम था? HttpURLConnection GetInputStream में GetOutputStream पर जो भी कनेक्शन स्थापित करने में सक्षम था, उसका पुन: उपयोग करेगा। – Arci

+0

Cont .: या यह getOutputStream और getInputStream के लिए एक नया और अलग कनेक्शन स्थापित करता है? इसके अलावा, अगर मैं कनेक्ट ओवरहेड प्राप्त करना चाहता हूं, तो मेरे टाइमर को रखने के लिए उचित जगह GetOutputStream के पहले और बाद में है। अगर मैं पढ़ा ओवरहेड प्राप्त करना चाहता हूं, तो मेरा टाइमर डालने के लिए उचित जगह getInputStream के पहले और बाद में है। – Arci

+0

याद रखें कि javadoc getInputStream के बारे में क्या कहता है और GetOutputStream: 'इस कनेक्शन को लिखने वाली आउटपुट स्ट्रीम देता है।' और 'इस खुले कनेक्शन से पढ़ने वाली इनपुट स्ट्रीम लौटाता है।'। आउटपुटस्ट्रीम और इनपुटस्ट्रीम कनेक्शन से अलग हैं। – jmort253

11

टिम ब्रै ने एक संक्षिप्त चरण-दर-चरण प्रस्तुत किया, जिसमें कहा गया कि openConnection() वास्तविक कनेक्शन स्थापित नहीं करता है। इसके बजाय, जब तक आप getInputStream() या GetOutputStream() प्राप्त विधियों को कॉल नहीं करते हैं, तब तक एक वास्तविक HTTP कनेक्शन स्थापित नहीं होता है।

http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection

1

जो बिंदु पर HTTPURLConnection दिए गए URL से कनेक्शन स्थापित करने की कोशिश करता है?

यूआरएल में नामित बंदरगाह पर, अन्यथा एचटीटीपीएस के लिए HTTP और 443 के लिए 80। मेरा मानना ​​है कि यह दस्तावेज है।

मुझे किस बिंदु पर पता चलेगा कि मैं सफलतापूर्वक कनेक्शन स्थापित करने में सक्षम था?

जब आप getInputStream() या getOutputStream() या getResponseCode() को अपवाद प्राप्त किए बिना कॉल करते हैं।

एक कनेक्शन स्थापित कर रहे हैं और एक चरण/विधि कॉल में किए गए वास्तविक अनुरोध को भेज रहे हैं? यह क्या तरीका है?

नहीं और कोई नहीं।

क्या आप getOutputStream के कार्य को समझा सकते हैं और layman की अवधि में getInputStream को समझ सकते हैं?

उनमें से कोई भी पहले आवश्यक होने पर कनेक्ट करता है, फिर आवश्यक स्ट्रीम देता है।

मुझे पता है कि जब मैं सर्वर से कनेक्ट करने का प्रयास कर रहा हूं, तो मुझे GetOutputStream पर एक अपवाद मिलता है। क्या इसका मतलब यह है कि जब मैं GetOutputStream का आह्वान करता हूं तो HTTPURLConnection केवल कनेक्शन स्थापित करना शुरू कर देगा? GetInputStream के बारे में कैसे? चूंकि मैं getInputStream पर प्रतिक्रिया प्राप्त करने में सक्षम हूं, तो क्या इसका मतलब यह है कि मैंने getOutputStream पर अभी तक कोई अनुरोध नहीं भेजा है, लेकिन बस एक कनेक्शन स्थापित करता है? जब मैं getInputStream का आह्वान करता हूं तो प्रतिक्रिया के लिए अनुरोध करने के लिए HttpURLConnection सर्वर पर वापस जाएं?

ऊपर देखें।

क्या मैं यह कहने में सही हूं कि openConnection बस एक नया कनेक्शन ऑब्जेक्ट बनाता है लेकिन अभी तक कोई कनेक्शन स्थापित नहीं करता है?

हां।

मैं ओवरहेड पढ़ने और ओवरहेड को कैसे जोड़ सकता हूं?

कनेक्ट करें: समय प्राप्त करें इनआउटस्ट्रीम() या getOutputStream() वापस लौटता है, जिसे आप पहले कॉल करते हैं। पढ़ें: ईओएस प्राप्त करने के लिए पहले पढ़ने से पहले शुरू करें।

+0

मुझे लगता है कि ओपी का मतलब है कि कौन सा बिंदु कनेक्शन स्थापित किया गया है और किस बिंदु पर हम कनेक्शन की स्थिति जान सकते हैं। बंदरगाह यूआरएल कनेक्ट नहीं है। मुझे लगता है कि इसे ओपनकनेक्शन() और getInoutStream()/getOutputStream()/getResponseCode() के उत्तर में निर्देशित किया गया था। –

1

HTTPURL कनेक्शन किस URL पर दिए गए यूआरएल से कनेक्शन स्थापित करने का प्रयास करता है?

यह स्पष्ट लायक है, वहाँ 'UrlConnection' उदाहरण है और फिर वहाँ अंतर्निहित टीसीपी/आईपी/SSL सॉकेट कनेक्शन, 2 अलग अवधारणाओं है। 'UrlConnection' या 'HttpUrlConnection' उदाहरण एक HTTP पृष्ठ अनुरोध का पर्याय बन गया है, और जब आप url.openConnection() को कॉल करते हैं तो बनाया जाता है। लेकिन यदि आप एक 'url' उदाहरण से एकाधिक url.openConnection() करते हैं तो यदि आप भाग्यशाली हैं, तो वे उसी टीसीपी/आईपी सॉकेट और एसएसएल हैंडशेकिंग सामान का पुन: उपयोग करेंगे ... यदि आप हैं तो अच्छा है एक ही सर्वर पर बहुत से पृष्ठ अनुरोध कर रहे हैं, विशेष रूप से अच्छा अगर आप एसएसएल का उपयोग कर रहे हैं जहां सॉकेट स्थापित करने का ओवरहेड बहुत अधिक है।

देखें: HttpURLConnection implementation