HTTP अनुरोधों को आग और संभालने के लिए java.net.URL कनेक्शन का उपयोग कैसे करें




httprequest httpurlconnection (10)

सबसे पहले अस्वीकरण पहले: पोस्ट कोड स्निपेट सभी बुनियादी उदाहरण हैं। आपको तुच्छ IOException s और IOException तरह NullPointerException , ArrayIndexOutOfBoundsException और स्वयं को प्रबंधित करने की आवश्यकता होगी।

तैयार कर रहे हैं

हमें सबसे पहले कम से कम यूआरएल और वर्णमाला जानने की जरूरत है। पैरामीटर वैकल्पिक हैं और कार्यात्मक आवश्यकताओं पर निर्भर करते हैं।

String url = "http://example.com";
String charset = "UTF-8";  // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name()
String param1 = "value1";
String param2 = "value2";
// ...

String query = String.format("param1=%s&param2=%s", 
     URLEncoder.encode(param1, charset), 
     URLEncoder.encode(param2, charset));

क्वेरी पैरामीटर name=value प्रारूप में होना चाहिए और इसके द्वारा संयोजित किया जाना चाहिए। आप सामान्य रूप से URLEncoder#encode() का उपयोग कर निर्दिष्ट वर्णमाला के साथ क्वेरी पैरामीटर को URL-encode भी करेंगे।

String#format() बस सुविधा के लिए है। मैं इसे पसंद करता हूं जब मुझे स्ट्रिंग कॉन्सटेनेशन ऑपरेटर + दो बार से अधिक की आवश्यकता होगी।

(वैकल्पिक रूप से) क्वेरी पैरामीटर के साथ HTTP GET अनुरोध को फायर करना

यह एक छोटा काम है। यह डिफ़ॉल्ट अनुरोध विधि है।

URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...

किसी भी क्वेरी स्ट्रिंग को यूआरएल के साथ संयोजित किया जाना चाहिए ?Accept-Charset हेडर सर्वर को संकेत दे सकता है कि पैरामीटर एन्कोडिंग क्या कर रहे हैं। यदि आप कोई क्वेरी स्ट्रिंग नहीं भेजते हैं, तो आप Accept-Charset शीर्षलेख को दूर छोड़ सकते हैं। यदि आपको कोई शीर्षलेख सेट करने की आवश्यकता नहीं है, तो आप URL#openStream() शॉर्टकट विधि का भी उपयोग कर सकते हैं।

InputStream response = new URL(url).openStream();
// ...

किसी भी तरह से, यदि दूसरी तरफ एक HttpServlet , तो इसकी doGet() विधि को कॉल किया जाएगा और पैरामीटर HttpServletRequest#getParameter() द्वारा उपलब्ध होंगे।

परीक्षण उद्देश्यों के लिए, आप प्रतिक्रिया शरीर को नीचे के रूप में stdout प्रिंट कर सकते हैं:

try (Scanner scanner = new Scanner(response)) {
    String responseBody = scanner.useDelimiter("\\A").next();
    System.out.println(responseBody);
}

क्वेरी पैरामीटर के साथ एक HTTP POST अनुरोध फायरिंग

URLConnection#setDoOutput() को true सेट करने से अनुरोध विधि को POST पर सेट किया जाता है। वेब फॉर्म के रूप में मानक HTTP पोस्ट प्रकार application/x-www-form-urlencoded जिसमें क्वेरी स्ट्रिंग अनुरोध निकाय को लिखा गया है।

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);

try (OutputStream output = connection.getOutputStream()) {
    output.write(query.getBytes(charset));
}

InputStream response = connection.getInputStream();
// ...

नोट: जब भी आप प्रोग्रामेटिक रूप से एक HTML फॉर्म जमा करना चाहते हैं, तो क्वेरी स्ट्रिंग में किसी भी <input type="hidden"> तत्वों के name=value जोड़े को लेना न भूलें और निश्चित रूप से name=value जोड़ी <input type="submit"> तत्व जिसे आप प्रोग्रामेटिक रूप से "प्रेस" करना चाहते हैं (क्योंकि आमतौर पर सर्वर पक्ष में इसका उपयोग किया जाता है ताकि बटन दबाया जा सके और यदि ऐसा है, तो कौन सा)।

आप प्राप्त java.net.URLConnection को HttpURLConnection भी डाल सकते हैं और इसके बजाय इसके HttpURLConnection#setRequestMethod() उपयोग कर सकते हैं। लेकिन अगर आप आउटपुट के लिए कनेक्शन का उपयोग करने की कोशिश कर रहे हैं तो आपको अभी भी URLConnection#setDoOutput() को true पर सेट करने की आवश्यकता true

HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...

किसी भी तरह से, यदि दूसरी तरफ एक HttpServlet , तो इसकी doPost() विधि को कॉल किया जाएगा और पैरामीटर HttpServletRequest#getParameter() द्वारा उपलब्ध होंगे।

वास्तव में HTTP अनुरोध को फायरिंग

आप URLConnection#connect() साथ HTTP अनुरोध को स्पष्ट रूप से आग लगा सकते हैं, लेकिन जब आप HTTP प्रतिक्रिया के बारे में कोई जानकारी प्राप्त करना चाहते हैं, तो अनुरोध को स्वचालित रूप से मांग पर निकाल दिया जाएगा, जैसे URLConnection#getInputStream() और अन्य का उपयोग कर प्रतिक्रिया निकाय। उपर्युक्त उदाहरण वास्तव में ऐसा करते connect() , इसलिए connect() कॉल वास्तव में अनिवार्य है।

HTTP प्रतिक्रिया जानकारी एकत्रित करना

  1. HTTP प्रतिक्रिया स्थिति :

    आपको यहां एक HttpURLConnection आवश्यकता है। यदि आवश्यक हो तो इसे पहले कास्ट करें।

    int status = httpConnection.getResponseCode();
    
  2. HTTP प्रतिक्रिया शीर्षलेख :

    for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
        System.out.println(header.getKey() + "=" + header.getValue());
    }
    
  3. HTTP प्रतिक्रिया एन्कोडिंग :

    जब Content-Type में एक charset पैरामीटर होता है, तो प्रतिक्रिया निकाय संभवतः टेक्स्ट आधारित होता है और हम प्रतिक्रिया-शरीर को सर्वर-साइड निर्दिष्ट वर्ण एन्कोडिंग के साथ संसाधित करना चाहते हैं।

    String contentType = connection.getHeaderField("Content-Type");
    String charset = null;
    
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    
    if (charset != null) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(response, charset))) {
            for (String line; (line = reader.readLine()) != null;) {
                // ... System.out.println(line) ?
            }
        }
    } else {
        // It's likely binary content, use InputStream/OutputStream.
    }
    

सत्र बनाए रखना

सर्वर साइड सत्र आमतौर पर कुकी द्वारा समर्थित होता है। कुछ वेब फ़ॉर्मों की आवश्यकता होती है कि आप लॉग इन हैं और / या किसी सत्र द्वारा ट्रैक किए जाते हैं। कुकीज़ को बनाए रखने के लिए आप कुकी CookieHandler एपीआई का उपयोग कर सकते हैं। सभी HTTP अनुरोध भेजने से पहले आपको CookiePolicy की ACCEPT_ALL CookieManager साथ CookieManager तैयार करने की आवश्यकता है।

// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

ध्यान दें कि यह हमेशा सभी परिस्थितियों में ठीक से काम नहीं करने के लिए जाना जाता है। यदि यह आपके लिए विफल रहता है, तो सबसे अच्छा कुकी हेडर मैन्युअल रूप से इकट्ठा करना और सेट करना है। आपको मूल रूप से लॉगिन या पहले GET अनुरोध की प्रतिक्रिया से सभी Set-Cookie शीर्षकों को पकड़ने की आवश्यकता है और फिर बाद के अनुरोधों के माध्यम से इसे पास करना होगा।

// Gather all cookies on the first request.
URLConnection connection = new URL(url).openConnection();
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
// ...

// Then use the same cookies on all subsequent requests.
connection = new URL(url).openConnection();
for (String cookie : cookies) {
    connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
}
// ...

split(";", 2)[0] कुकी गुणों से छुटकारा पाने के लिए है जो सर्वर की तरफ की expires जैसे कि expires , path इत्यादि। वैकल्पिक रूप से, आप cookie.substring(0, cookie.indexOf(';')) split() बजाय split()

स्ट्रीमिंग मोड

HttpURLConnection वास्तव में इसे भेजने से पहले पूरे अनुरोध निकाय को डिफ़ॉल्ट रूप से बफर करेगा, भले ही आपने HttpURLConnection connection.setRequestProperty("Content-Length", contentLength); का उपयोग कर स्वयं एक निश्चित सामग्री लंबाई निर्धारित की हो connection.setRequestProperty("Content-Length", contentLength); । जब भी आप बड़े POST अनुरोध (जैसे फाइल अपलोड करना) भेजते हैं तो यह OutOfMemoryException s का कारण बन सकता है। इससे बचने के लिए, आप HttpURLConnection#setFixedLengthStreamingMode() सेट करना चाहते हैं।

httpConnection.setFixedLengthStreamingMode(contentLength);

लेकिन यदि सामग्री की लंबाई वास्तव में पहले से ज्ञात नहीं है, तो आप तदनुसार HttpURLConnection#setChunkedStreamingMode() को सेट करके HttpURLConnection#setChunkedStreamingMode() स्ट्रीमिंग मोड का उपयोग कर सकते हैं। यह HTTP Transfer-Encoding हेडर को चंक करने के लिए सेट करेगा जो अनुरोध निकाय को भाग में भेजे जाने के लिए मजबूर करेगा। नीचे दिया गया उदाहरण शरीर को 1 केबी के टुकड़ों में भेज देगा।

httpConnection.setChunkedStreamingMode(1024);

उपभोक्ता अभिकर्ता

ऐसा हो सकता है कि एक अनुरोध एक अप्रत्याशित प्रतिक्रिया देता है, जबकि यह वास्तविक वेब ब्राउज़र के साथ ठीक काम करता है। सर्वर पक्ष शायद User-Agent अनुरोध शीर्षलेख के आधार पर अनुरोध अवरुद्ध कर रहा है। URLConnection डिफ़ॉल्ट रूप से इसे Java/1.6.0_19 सेट Java/1.6.0_19 जहां अंतिम भाग स्पष्ट रूप से Java/1.6.0_19 संस्करण है। आप इसे निम्नानुसार ओवरराइड कर सकते हैं:

connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); // Do as if you're using Chrome 41 on Windows 7.

हालिया ब्राउज़र से उपयोगकर्ता-एजेंट स्ट्रिंग का उपयोग करें।

गलती संभालना

यदि HTTP प्रतिक्रिया कोड 4nn (क्लाइंट त्रुटि) या 5nn (सर्वर त्रुटि) है, तो आप यह देखने के लिए HttpURLConnection#getErrorStream() को पढ़ना HttpURLConnection#getErrorStream() कि सर्वर ने कोई उपयोगी त्रुटि जानकारी भेजी है या नहीं।

InputStream error = ((HttpURLConnection) connection).getErrorStream();

यदि HTTP प्रतिक्रिया कोड -1 है, तो कनेक्शन और प्रतिक्रिया हैंडलिंग के साथ कुछ गलत हो गया है। HttpURLConnection कार्यान्वयन पुराने HttpURLConnection में कनेक्शन को जिंदा रखने के साथ कुछ हद तक छोटी है। आप http.keepAlive सिस्टम प्रॉपर्टी को false सेट करके इसे बंद करना चाहते हैं। आप अपने आवेदन की शुरुआत में प्रोग्रामेटिक रूप से ऐसा कर सकते हैं:

System.setProperty("http.keepAlive", "false");

फाइल अपलोड कर रहा है

आप आम तौर पर मिश्रित पोस्ट सामग्री (बाइनरी और वर्ण डेटा) के लिए multipart/form-data एन्कोडिंग का उपयोग करेंगे। एन्कोडिंग RFC2388 में वर्णित अधिक विस्तार से है।

String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

try (
    OutputStream output = connection.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
) {
    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF).append(param).append(CRLF).flush();

    // Send text file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();
    Files.copy(textFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    Files.copy(binaryFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF).flush();
}

यदि दूसरी तरफ एक HttpServlet , तो इसकी doPost() विधि को कॉल किया जाएगा और भागों HttpServletRequest#getPart() द्वारा नोट किया जाएगा (नोट, इस प्रकार getParameter() और इतने पर नहीं!)। getPart() विधि अपेक्षाकृत नई है, इसे सर्वलेट 3.0 (ग्लासफ़िश 3, टॉमकैट 7, आदि) में पेश किया गया है। सर्वलेट 3.0 से पहले, आपकी सबसे अच्छी पसंद एक multipart/form-data अनुरोध को पार्स करने के लिए अपाचे कॉमन्स फ़ाइल अपलोड का उपयोग कर रही है। FileUpload और Servelt 3.0 दृष्टिकोण दोनों के उदाहरणों के लिए यह उत्तर भी देखें।

अविश्वसनीय या गलत कॉन्फ़िगर किए गए HTTPS साइटों से निपटना

कभी-कभी आपको एक HTTPS URL कनेक्ट करने की आवश्यकता होती है, शायद इसलिए कि आप एक वेब स्क्रैपर लिख रहे हैं। उस स्थिति में, आप शायद javax.net.ssl.SSLException: Not trusted server certificate सामना कर सकते हैं javax.net.ssl.SSLException: Not trusted server certificate कुछ HTTPS साइट्स पर javax.net.ssl.SSLException: Not trusted server certificate नहीं है जो अपने SSL प्रमाणपत्र को अद्यतित नहीं रखते हैं, या java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found या javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name कुछ गलत कॉन्फ़िगर किए गए HTTPS साइट्स पर javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name

आपके वेब स्क्रैपर क्लास में निम्न एक-बार-चलने वाले static प्रारंभकर्ता को HttpsURLConnection को उन HTTPS साइटों के रूप में अधिक उदार बनाना चाहिए और इस प्रकार उन अपवादों को और फेंकना नहीं चाहिए।

static {
    TrustManager[] trustAllCertificates = new TrustManager[] {
        new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null; // Not relevant.
            }
            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
        }
    };

    HostnameVerifier trustAllHostnames = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true; // Just allow them all.
        }
    };

    try {
        System.setProperty("jsse.enableSNIExtension", "false");
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCertificates, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(trustAllHostnames);
    }
    catch (GeneralSecurityException e) {
        throw new ExceptionInInitializerError(e);
    }
}

आखरी श्ब्द

Apache HttpComponents HttpClient इस सब में अधिक सुविधाजनक है :)

पार्सिंग और एचटीएमएल निकालने

यदि आप चाहते हैं कि HTML से डेटा पार्सिंग और निकालना है, तो बेहतर है कि एक HTML पार्सर जैसे Jsoup का उपयोग करें

java.net.URLConnection का उपयोग अक्सर यहां अक्सर पूछे जाने पर किया जाता है, और ओरेकल ट्यूटोरियल इसके बारे में बहुत संक्षिप्त है।

यह ट्यूटोरियल मूल रूप से केवल एक जीईटी अनुरोध को आग लगाने और प्रतिक्रिया पढ़ने के लिए दिखाता है। यह कहीं भी नहीं समझाता है कि दूसरों के बीच इसका उपयोग कैसे करें POST अनुरोध करें, अनुरोध शीर्षलेख सेट करें, प्रतिक्रिया शीर्षलेख पढ़ें, कुकीज़ से निपटें, एक HTML फॉर्म सबमिट करें, फ़ाइल अपलोड करें आदि।

तो, मैं "उन्नत" HTTP अनुरोधों को आग और संभालने के लिए java.net.URLConnection का उपयोग कैसे कर सकता हूं?


अद्यतन करें

जावा 9 के साथ भेजा गया नया HTTP क्लाइंट लेकिन jdk.incubator.httpclient नामक इनक्यूबेटर मॉड्यूल के हिस्से के रूप में। इनक्यूबेटर मॉड्यूल डेवलपर्स के हाथों में गैर-अंतिम एपीआई डालने का माध्यम है जबकि एपीआई भविष्य में रिलीज में अंतिम रूप देने या हटाने की दिशा में प्रगति करता है।

जावा 9 में, आप एक GET अनुरोध भेज सकते हैं जैसे:

// GET
HttpResponse response = HttpRequest
    .create(new URI("http://www..com"))
    .headers("Foo", "foovalue", "Bar", "barvalue")
    .GET()
    .response();

फिर आप लौटे HttpResponse जांच कर सकते हैं:

int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());

चूंकि यह नया HTTP क्लाइंट अंदर है java.httpclient jdk.incubator.httpclient मॉड्यूल, आपको इस module-info.java फ़ाइल में इस निर्भरता की घोषणा करनी चाहिए:

module com.foo.bar {
    requires jdk.incubator.httpclient;
}

मेरा सुझाव है कि आप kevinsawicki/http-request पर कोड को kevinsawicki/http-request , मूल रूप से HttpUrlConnection शीर्ष पर एक रैपर यह एक बहुत ही सरल API प्रदान करता है यदि आप अभी अनुरोध करना चाहते हैं या आप स्रोतों को देख सकते हैं (यह बहुत बड़ा नहीं है) यह देखने के लिए कि कनेक्शन कैसे प्रबंधित किए जाते हैं।

उदाहरण: सामग्री प्रकार application/json और कुछ क्वेरी पैरामीटर के साथ एक GET अनुरोध GET :

// GET http://google.com?q=baseball%20gloves&size=100
String response = HttpRequest.get("http://google.com", true, "q", "baseball gloves", "size", 100)
        .accept("application/json")
        .body();
System.out.println("Response was: " + response);

एसओ पर इस और अन्य प्रश्नों से प्रेरित, मैंने एक न्यूनतम ओपन सोर्स basic-http-client जो यहां पाए गए अधिकांश तकनीकों का प्रतीक है।

google-http-java-client भी एक महान ओपन सोर्स संसाधन है।


मैं भी इस प्रतिक्रिया से बहुत प्रेरित था।

मैं अक्सर उन परियोजनाओं पर हूं जहां मुझे कुछ HTTP करने की ज़रूरत है, और मैं कई तृतीय पक्ष निर्भरताओं को नहीं लेना चाहता हूं (जो दूसरों को लाता है और इसी तरह आदि)

मैंने इस बातचीत में से कुछ के आधार पर अपनी खुद की उपयोगिताएं लिखना शुरू कर दिया (कहीं भी नहीं किया गया):

package org.boon.utils;


import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import static org.boon.utils.IO.read;

public class HTTP {

फिर केवल एक गुच्छा या स्थिर तरीके हैं।

public static String get(
        final String url) {

    Exceptions.tryIt(() -> {
        URLConnection connection;
        connection = doGet(url, null, null, null);
        return extractResponseString(connection);
    });
    return null;
}

public static String getWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, null, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String getWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}
public static String getWithCharSet(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType,
        String charSet) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, charSet);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

फिर पोस्ट करें ...

public static String postBody(
        final String url,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, null, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String postBodyWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, headers, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}



public static String postBodyWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, null, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}


public static String postBodyWithCharset(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String charSet,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, charSet, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}

private static URLConnection doPost(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset, String body
                                    ) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    connection.setDoOutput(true);
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);


    IO.write(connection.getOutputStream(), body, IO.CHARSET);
    return connection;
}

private static void manageHeaders(Map<String, ? extends Object> headers, URLConnection connection) {
    if (headers != null) {
        for (Map.Entry<String, ? extends Object> entry : headers.entrySet()) {
            connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
        }
    }
}

private static void manageContentTypeHeaders(String contentType, String charset, URLConnection connection) {
    connection.setRequestProperty("Accept-Charset", charset == null ? IO.CHARSET : charset);
    if (contentType!=null && !contentType.isEmpty()) {
        connection.setRequestProperty("Content-Type", contentType);
    }
}

private static URLConnection doGet(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);

    return connection;
}

private static String extractResponseString(URLConnection connection) throws IOException {
/* Handle input. */
    HttpURLConnection http = (HttpURLConnection)connection;
    int status = http.getResponseCode();
    String charset = getCharset(connection.getHeaderField("Content-Type"));

    if (status==200) {
        return readResponseBody(http, charset);
    } else {
        return readErrorResponseBody(http, status, charset);
    }
}

private static String readErrorResponseBody(HttpURLConnection http, int status, String charset) {
    InputStream errorStream = http.getErrorStream();
    if ( errorStream!=null ) {
        String error = charset== null ? read( errorStream ) :
            read( errorStream, charset );
        throw new RuntimeException("STATUS CODE =" + status + "\n\n" + error);
    } else {
        throw new RuntimeException("STATUS CODE =" + status);
    }
}

private static String readResponseBody(HttpURLConnection http, String charset) throws IOException {
    if (charset != null) {
        return read(http.getInputStream(), charset);
    } else {
        return read(http.getInputStream());
    }
}

private static String getCharset(String contentType) {
    if (contentType==null)  {
        return null;
    }
    String charset = null;
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    charset = charset == null ?  IO.CHARSET : charset;

    return charset;
}

खैर, आप विचार समझ गए....

यहां परीक्षण हैं:

static class MyHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException {

        InputStream requestBody = t.getRequestBody();
        String body = IO.read(requestBody);
        Headers requestHeaders = t.getRequestHeaders();
        body = body + "\n" + copy(requestHeaders).toString();
        t.sendResponseHeaders(200, body.length());
        OutputStream os = t.getResponseBody();
        os.write(body.getBytes());
        os.close();
    }
}


@Test
public void testHappy() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9212), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9212/test", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.postBodyWithCharset("http://localhost:9212/test", headers, "text/plain", "UTF-8", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    response = HTTP.postBodyWithHeaders("http://localhost:9212/test", headers, "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.get("http://localhost:9212/test");

    System.out.println(response);


    response = HTTP.getWithHeaders("http://localhost:9212/test", headers);

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithContentType("http://localhost:9212/test", headers, "text/plain");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithCharSet("http://localhost:9212/test", headers, "text/plain", "UTF-8");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

@Test
public void testPostBody() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9220), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBody("http://localhost:9220/test", "hi mom");

    assertTrue(response.contains("hi mom"));


    Thread.sleep(10);

    server.stop(0);


}

@Test(expected = RuntimeException.class)
public void testSad() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9213), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9213/foo", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

आप बाकी को यहां पा सकते हैं:

https://github.com/RichardHightower/boon

मेरा लक्ष्य उन सामान्य चीजों को प्रदान करना है जो एक और अधिक आसान तरीके से करना चाहते हैं ....


शुरुआत में मुझे इस article गुमराह किया गया था जो HttpClient पक्ष HttpClient

बाद में मुझे एहसास हुआ कि HttpURLConnection इस article से बने रहने जा रहा है

Google ब्लॉग के अनुसार :

अपाचे HTTP क्लाइंट में एक्लेयर और फियोयो पर कम कीड़े हैं। इन रिलीज के लिए यह सबसे अच्छा विकल्प है। जिंजरब्रेड के लिए, HttpURLConnection सबसे अच्छा विकल्प है। इसका सरल एपीआई और छोटा आकार एंड्रॉइड के लिए यह बहुत अच्छा बनाता है।

पारदर्शी संपीड़न और प्रतिक्रिया कैशिंग नेटवर्क उपयोग को कम करने, गति में सुधार और बैटरी बचाने के लिए। नए अनुप्रयोगों को HttpURLConnection का उपयोग करना चाहिए; यह वह जगह है जहां हम अपनी ऊर्जा आगे बढ़ेंगे।

प्रवाह rapidvaluesolutions.com/tech_blog/… और कुछ अन्य ढेर को पढ़ने के बाद, मुझे आश्वस्त है कि HttpURLConnection लंबे समय तक रहने के लिए जा रहा है।

HttpURLConnections के पक्ष में कुछ एसई प्रश्न:

एंड्रॉइड पर, UrlEncodedFormEntity का उपयोग किए बिना यूआरएल एनकोडेड फॉर्म डेटा के साथ एक POST अनुरोध करें

एचटीपीपोस्ट जावा प्रोजेक्ट में काम करता है, एंड्रॉइड में नहीं


HTTP यूआरएल हिट्स के साथ 2 विकल्प हैं: जीईटी / पोस्ट करें

अनुरोध प्राप्त करें: -

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url";
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
System.out.println(String.valueOf(http_conn.getResponseCode()));

POST अनुरोध: -

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url"
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
http_conn.setDoOutput(true);
PrintWriter out = new PrintWriter(http_conn.getOutputStream());
if (urlparameter != null) {
   out.println(urlparameter);
}
out.close();
out = null;
System.out.println(String.valueOf(http_conn.getResponseCode()));

I recomend http-request built on apache http api. (I'm a developer)

Perform HTTP GET request

static final HttpRequest<String> httpRequest =
     HttpRequestBuilder.createGet(someUri, String.class)
     .responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();

ResponseHandler<String> responseHandler = httpRequest.execute(requestParameters);

int statusCode = responseHandler.getStatusCode();
String responseBody = responseHandler.get(); // see javadoc of get method

या

 ResponseHandler<String> responseHandler = 
      httpRequest.executeWithQuery(queryString); //queryString example "param1=param1&param2=param2"

Perform HTTP POST request

Replace HttpRequestBuilder.createGet to HttpRequestBuilder.createPost

Add headers

static final HttpRequest<String> httpRequest =
      HttpRequestBuilder.createGet(someUri, String.class)
           .responseDeserializer(ResponseDeserializer.ignorableDeserializer())
           .addDefaultHeader("Accept", "application/json")
           .build();

Convert response to type

let's say response is JSON and you know it

{"name":"myname","lastname":"mylastname","age":25}

You must create class User:

public User{
    private String Name;
    private String Lastname;
    private int Age;

   // getters and setters
}

static final HttpRequest<User> httpRequest =
     HttpRequestBuilder.createGet(someUri, User.class).build();

ResponseHandler<User> responseHandler = httpRequest.execute(requestParameters);
User userFromResponse = responseHandler.orElse(null); //returns null if content isn't present
System.out.print(user.getName()); //myname

Note: You don't need to worry about Exceptions. All exceptions is wrapped.


if you are using http get please remove this line

urlConnection.setDoOutput(true);

OkHttp भी है, जो एक HTTP क्लाइंट है जो डिफ़ॉल्ट रूप से कुशल है:

  • HTTP / 2 समर्थन एक ही मेजबान को सॉकेट साझा करने के लिए सभी अनुरोधों की अनुमति देता है।
  • कनेक्शन पूलिंग अनुरोध विलंबता को कम कर देता है (यदि HTTP / 2 उपलब्ध नहीं है)।
  • पारदर्शी जीजेआईपी डाउनलोड आकार को कम करता है।
  • प्रतिक्रिया कैशिंग दोहराए गए अनुरोधों के लिए पूरी तरह से नेटवर्क से बचाती है।

पहले OkHttpClient का एक उदाहरण OkHttpClient :

OkHttpClient client = new OkHttpClient();

फिर, अपना GET अनुरोध तैयार करें:

Request request = new Request.Builder()
      .url(url)
      .build();

अंत में, तैयार Request भेजने के लिए OkHttpClient का उपयोग करें:

Response response = client.newCall(request).execute();

अधिक जानकारी के लिए, आप ओकेएचटीपी के दस्तावेज़ीकरण से परामर्श ले सकते हैं





urlconnection