Apache HttpClient API में CloseableHttpClient और HttpClient के बीच अंतर क्या है?


83

मैं हमारी कंपनी द्वारा विकसित एक एप्लिकेशन का अध्ययन कर रहा हूं। यह Apache HttpClient लाइब्रेरी का उपयोग करता है। स्रोत कोड में यह HttpClientएक सर्वर से कनेक्ट करने के लिए उदाहरण बनाने के लिए कक्षा का उपयोग करता है।

मैं Apache HttpClient के बारे में सीखना चाहता हूं और मैंने इस उदाहरण के सेट को गर्त में डाल दिया है । के CloseableHttpClientबजाय सभी उदाहरणों का उपयोग करते हैं HttpClient। इसलिए मुझे लगता CloseableHttpClientहै कि इसका एक विस्तारित संस्करण है HttpClient। अगर ऐसा है तो मेरे दो सवाल हैं:

  • इन दोनों के बीच क्या अंतर है?
  • मेरे नए विकास के लिए किस वर्ग का उपयोग करने की सिफारिश की गई है?

7
दस्तावेज़ मुझे बहुत स्पष्ट लगता है: "HttpClient का आधार कार्यान्वयन जो क्लोजेबल को भी लागू करता है" - HttpClient एक इंटरफ़ेस है; CloseableHttpClient एक अमूर्त वर्ग है, लेकिन क्योंकि यह AutoCloseable को लागू करता है आप इसे एक कोशिश के साथ संसाधनों के बयान में उपयोग कर सकते हैं।
जॉन स्केट

3
@JonSkeet यह बहुत स्पष्ट है, लेकिन HttpClientउदाहरणों को बंद करना कितना महत्वपूर्ण है ? यदि यह महत्वपूर्ण है, तो close()विधि मूल इंटरफ़ेस का हिस्सा क्यों नहीं है?
जूल्स

3
@ जूल्स: मुझे डर है कि मुझे इस बात का जवाब देने के लिए पर्याप्त जानकारी नहीं है कि:
जॉन स्कीट

अंतर्निहित कनेक्शन से बेसिक इंटरफेस का हिस्सा होने की आवश्यकता नहीं है क्योंकि अंतर्निहित कनेक्शन स्वचालित रूप से कनेक्शन प्रबंधक को वापस जारी किया जाता है
जेरिल कुरुविला

जवाबों:


100
  • HttpClient एपीआई का मुख्य प्रवेश बिंदु HttpClient इंटरफ़ेस है।
  • HttpClient का सबसे आवश्यक कार्य HTTP विधियों को निष्पादित करना है।
  • एक HTTP पद्धति के निष्पादन में एक या कई HTTP अनुरोध / HTTP प्रतिक्रिया एक्सचेंज शामिल हैं, जो आमतौर पर HttpClient द्वारा आंतरिक रूप से नियंत्रित किए जाते हैं।

  • CloseableHttpClient एक अमूर्त वर्ग है जो HttpClient का आधार कार्यान्वयन है जो java.io.Closeable को भी लागू करता है।
  • यहाँ इसके सरलतम रूप में अनुरोध निष्पादन प्रक्रिया का एक उदाहरण दिया गया है:

    क्लोज़ेबलहेटप्लीकंट httpclient = HttpClients.createDefault ();
    HttpGet httpget = नया HttpGet ("http: // localhost /");
    क्लोज़ेबलहेट्रप्रस्पॉन्स प्रतिक्रिया = httpclient.execute (httpget);
    प्रयत्न {
        //कुछ करो
    } आखिरकार {
        response.close ();
    }

  • HttpClient संसाधन डीललोकेशन : जब कोई उदाहरण CloseableHttpClient की आवश्यकता नहीं होती है और वह स्कोप से बाहर जाने वाला होता है, तो इससे जुड़े कनेक्शन प्रबंधक को CloseableHttpClient को # बंद () विधि कहकर बंद करना होगा।

    क्लोज़ेबलहेटप्लीकंट httpclient = HttpClients.createDefault ();
    प्रयत्न {
        //कुछ करो
    } आखिरकार {
        httpclient.close ();
    }

बुनियादी बातों को सीखने के लिए संदर्भ देखें ।


@ जावा 7 से बचाव करें, कोशिश-के-संसाधनों के विवरण का उपयोग यह सुनिश्चित करता है कि प्रत्येक संसाधन बयान के अंत में बंद हो। यह क्लाइंट के लिए और प्रत्येक प्रतिक्रिया के लिए दोनों का उपयोग किया जा सकता है

try(CloseableHttpClient httpclient = HttpClients.createDefault()){

    // e.g. do this many times
    try (CloseableHttpResponse response = httpclient.execute(httpget)) {
    //do something
    }

    //do something else with httpclient here
}

57
इस सवाल का जवाब तरह से देता है। HttpClient के पास कॉल करने से क्या होता है? यदि आप उचित समय / स्थानों पर क्लोज़ () कॉल नहीं करते हैं तो क्या आप कनेक्शन लीक करते हैं? क्या आपके पास कॉल करना () समय से पहले आपके प्रदर्शन को प्रभावित करता है जिसके कारण आपको फिर से कनेक्ट करना पड़ता है जब आपको वास्तव में ज़रूरत नहीं थी?
गिल्बर्टपिलज़

4
मैंने इस प्रश्न के उत्तर के लिए httpclient में कोड को देखा। उत्तर यह है कि आंतरिक राज्य को बंद करने के लिए करीबी विधि का उपयोग किया जाता है। HTTPClient के कुछ कार्यान्वयन (httpclient lib में) को पूल किए गए कनेक्शनों के लिए निरंतर संसाधनों जैसे कि पूल किए गए कनेक्शनों का उपयोग करने के लिए कॉन्फ़िगर किया जा सकता है और इस तरह की विधि के बिना आप जरूरत पड़ने पर इन संसाधनों को साफ नहीं कर सकते हैं।
डेड्रॉन

@SugarPudi उपरोक्त उदाहरण में, क्या हमें httpgetभी बंद करने की जरूरत है
कसुन सियामबलपिटिया

हम यहाँ अमूर्त वर्ग (क्लोसएबल हेटप्लीकेंट) पर तरीकों को कैसे लागू कर सकते हैं? क्या हमें पहले एक ठोस उपवर्ग नहीं बनाना चाहिए?
इलकार

@illcar इस अवधारणा को समझने के लिए कृपया उत्तर दें। stackoverflow.com/a/4321402/2830834
सागर पुदी

26

एक ही सवाल था। अन्य उत्तरों से पता नहीं लगता कि पास () वास्तव में आवश्यक क्यों है? इसके अलावा, ओप को HttpClient, एट अल के साथ काम करने का पसंदीदा तरीका जानने के लिए संघर्ष करना पड़ रहा था।


अपाचे के अनुसार :

// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST call CloseableHttpResponse#close() from a finally clause.

इसके अलावा, रिश्ते निम्नानुसार हैं:

HttpClient (इंटरफेस)

के द्वारा लागू किया गया:

CloseableHttpClient - सुरक्षित धागा।

DefaultHttpClient- थ्रेडसेफ़ कट आउट हटाए गए , HttpClientBuilderइसके बजाय उपयोग करें ।

HttpClientBuilder- थ्रेडसेफ़ नहीं, लेकिन थ्रेडसेफ़ बनाता है CloseableHttpClient

  • CUSTOM बनाने के लिए उपयोग करें CloseableHttpClient

HttpClients- थ्रेडसेफ़ नहीं, लेकिन थ्रेडसेफ़ बनाता है CloseableHttpClient

  • DEFAULT या MINIMAL बनाने के लिए उपयोग करें CloseableHttpClient

अपाचे के अनुसार पसंदीदा तरीका:

CloseableHttpClient httpclient = HttpClients.createDefault();

उदाहरण वे देता है httpclient.close()में finallyखंड, और यह भी का उपयोग करता है ResponseHandlerके रूप में अच्छी तरह से।


एक विकल्प के रूप में, जिस तरह से mkyong करता है वह थोड़ा दिलचस्प है, साथ ही:

HttpClient client = HttpClientBuilder.create().build();

वह client.close()कॉल नहीं दिखाता है, लेकिन मुझे लगता है कि यह आवश्यक है, क्योंकि clientअभी भी एक उदाहरण है CloseableHttpClient


15

अन्य उत्तरों से पता नहीं लगता है कि close()वास्तव में आवश्यक क्यों है? * २

जवाब पर संदेह "HttpClient संसाधन डीललोकेशन"।

यह पुराने 3.x httpcompenders doc में उल्लिखित है , जो लंबे समय से वापस है और 4.x HC से बहुत अंतर है। इसके अलावा स्पष्टीकरण इतना संक्षिप्त है कि यह नहीं कहता कि यह अंतर्निहित संसाधन क्या है।

मैंने 4.5.2 रिलीज सोर्स कोड पर कुछ शोध किया, CloseableHttpClient:close()मूल रूप से इसके कनेक्शन प्रबंधक को केवल बंद करने के कार्यान्वयन को पाया ।

(FYI करें) यही कारण है कि जब आप एक साझा PoolingClientConnectionManagerऔर कॉल क्लाइंट का उपयोग करते हैं close(), तो अपवाद java.lang.IllegalStateException: Connection pool shut downहोगा। बचने के लिए, setConnectionManagerSharedकाम करता है।

मैं हर एक अनुरोध के बाद करना पसंद नहीं करताCloseableHttpClient:close()

मैंने अनुरोध करते समय एक नया http क्लाइंट उदाहरण बनाया और अंत में इसे बंद कर दिया। इस मामले में, कॉल न करना बेहतर होगा close()। चूंकि, यदि कनेक्शन प्रबंधक के पास "साझा" ध्वज नहीं है, तो यह बंद हो जाएगा, जो कि एक अनुरोध के लिए बहुत महंगा है।

वास्तव में, मैं भी पुस्तकालय clj-http में पाया गया , Apache HC 4.5 पर एक क्लोजर आवरण, बिल्कुल भी कॉल नहीं करता है close()requestफ़ाइल core.clj में func देखें


1
क्या आप स्पष्ट कर सकते हैं कि हर अनुरोध के बाद यह सेटकनेक्शन मैनजरेडेड और कॉल बंद () के उपयोग से बेहतर क्यों है?
zyfo2

9

लाइब्रेरी HttpClientइंटरफ़ेस के अगले प्रमुख संस्करण में विस्तार करने जा रहा है Closeable। तब तक यह उपयोग करने की सिफारिश की जाती है CloseableHttpClientयदि पहले के 4.x संस्करणों (4.0, 4.1 और 4.2) के साथ संगतता की आवश्यकता नहीं है।


8

HttpClientएक वर्ग नहीं है, यह एक इंटरफ़ेस है। आप इसे अपने मतलब के तरीके में विकास के लिए उपयोग नहीं कर सकते।

आप जो चाहते हैं वह एक ऐसा वर्ग है जो HttpClientइंटरफ़ेस को लागू करता है, और वह है CloseableHttpClient


2

CloseableHttpClienthttpclient लाइब्रेरी का आधार वर्ग है, जो सभी कार्यान्वयन का उपयोग करता है। अन्य उपवर्ग अधिकांश भाग के लिए हैं।

HttpClientइस वर्ग और अन्य वर्गों के लिए एक इंटरफेस है।

फिर आपको CloseableHttpClientअपने कोड में उपयोग करना चाहिए , और इसे उपयोग करके बनाना चाहिए HttpClientBuilder। यदि आपको विशिष्ट व्यवहार जोड़ने के लिए क्लाइंट को लपेटने की आवश्यकता है, तो आपको इसके साथ रैप करने के बजाय अनुरोध और प्रतिक्रिया इंटरसेप्टर का उपयोग करना चाहिए HttpClient

यह उत्तर httpclient-4.3 के संदर्भ में दिया गया था।


0

जॉन स्कीट ने कहा:

दस्तावेज़ मुझे बहुत स्पष्ट लगता है: "HttpClient का आधार कार्यान्वयन जो क्लोजेबल को भी लागू करता है" - HttpClient एक इंटरफ़ेस है; CloseableHttpClient एक अमूर्त वर्ग है, लेकिन क्योंकि यह AutoCloseable को लागू करता है आप इसे एक कोशिश के साथ संसाधनों के बयान में उपयोग कर सकते हैं।

लेकिन फिर जूल्स ने पूछा:

@JonSkeet यह बहुत स्पष्ट है, लेकिन HttpClient उदाहरणों को बंद करना कितना महत्वपूर्ण है? यदि यह महत्वपूर्ण है, तो करीब () विधि मूल इंटरफ़ेस का हिस्सा क्यों नहीं है?

जूल्स का उत्तर

पास की जरूरत बुनियादी इंटरफ़ेस का हिस्सा नहीं है क्योंकि अंतर्निहित कनेक्शन प्रत्येक निष्पादन के बाद स्वचालित रूप से कनेक्शन प्रबंधक को वापस जारी किया जाता है

संसाधनों के साथ कथन को समायोजित करने के लिए। क्लोजेबल को लागू करना अनिवार्य है। इसलिए इसे CloseableHttpClient में शामिल किया गया ।

ध्यान दें:

AbstractHttpClient में क्लोज़ विधि जो क्लोसएबलहेटप्लीकेंट का विस्तार कर रही है, पदावनत है, मैं उसके लिए सोर्स कोड नहीं ढूंढ पा रहा था।


यह अभी भी "HttpClient उदाहरणों को बंद करने के लिए कितना महत्वपूर्ण है?"
विवेक चावड़ा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.