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


1945

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

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

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

जवाबों:


2710

पहले एक अस्वीकरण पहले: पोस्ट किए गए कोड स्निपेट सभी मूल उदाहरण हैं। तुच्छ IOExceptionएस और RuntimeExceptionएस की तरह संभालना होगा NullPointerException, ArrayIndexOutOfBoundsExceptionऔर खुद को संजोना होगा।


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

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

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प्रारूप में होना चाहिए और उनके अनुरूप होना चाहिए &। आप सामान्य रूप से उपयोग किए गए चारसेट के साथ क्वेरी पैरामीटर को URL-एनकोड भी करेंगे URLEncoder#encode()

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


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

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

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

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

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

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

परीक्षण के प्रयोजनों के लिए, आप नीचे दिए गए अनुसार प्रतिक्रिया निकाय को प्रिंट कर सकते हैं:

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

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

स्थापना URLConnection#setDoOutput()करने के लिए trueपरोक्ष पोस्ट करने के लिए अनुरोध विधि सेट। वेब फॉर्म के रूप में मानक HTTP POST 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 फॉर्म सबमिट करना चाहते हैं, तो name=valueकिसी भी <input type="hidden">तत्व के जोड़े को क्वेरी स्ट्रिंग में ले जाना न भूलें और निश्चित रूप name=valueसे उस <input type="submit">तत्व की जोड़ी भी जिसे आप प्रोग्रामेटिक रूप से "प्रेस" करना चाहते हैं (क्योंकि यदि बटन को दबाया गया था और यदि ऐसा है, तो कौन अलग है, यह आमतौर पर सर्वर साइड में उपयोग किया जाता है।

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

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

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


वास्तव में HTTP रिक्वेस्ट को फायर करना

आप स्पष्ट रूप से HTTP अनुरोध के साथ आग लगा सकते हैं URLConnection#connect(), लेकिन जब आप HTTP प्रतिक्रिया के बारे में कोई जानकारी प्राप्त करना चाहते हैं, जैसे कि प्रतिक्रिया निकाय का उपयोग करना URLConnection#getInputStream()आदि, तो अनुरोध स्वचालित रूप से मांग पर निकाल दिया जाएगा । उपरोक्त उदाहरण ठीक यही करते हैं, इसलिए यह 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 अनुरोध भेजने से पहले एक के CookieManagerसाथ तैयार करने की आवश्यकता है ।CookiePolicyACCEPT_ALL

// 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();
// ...

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

// 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, pathआदि वैकल्पिक रूप से, आप भी इस्तेमाल कर सकते हैं cookie.substring(0, cookie.indexOf(';'))के बजाय split()


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

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

httpConnection.setFixedLengthStreamingMode(contentLength);

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

httpConnection.setChunkedStreamingMode(1024);

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

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

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()क्या सर्वर ने कोई उपयोगी त्रुटि जानकारी भेजी है।

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

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

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

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

आप सामान्य रूप से multipart/form-dataमिश्रित POST सामग्री (बाइनरी और चरित्र डेटा) के लिए एन्कोडिंग का उपयोग करेंगे । एन्कोडिंग 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 से पहले, आपका सबसे अच्छा विकल्प एक अनुरोध को पार्स करने के लिए Apache Commons FileUpload का उपयोग कर रहा है multipart/form-dataइस उत्तर को भी FileUpload और Servelt 3.0 दृष्टिकोण दोनों के उदाहरणों के लिए देखें ।


अविश्वसनीय या गलत HTTPS साइटों से निपटना

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

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);
    }
}

आखरी श्ब्द

अपाचे HttpComponents HttpClient है बहुत अधिक यह सब में सुविधाजनक :)


HTML को पार्स करना और निकालना

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


119
आपको अपाचे लिंक को पहले रखना चाहिए, ताकि समाधान खोजने वाले लोग इसे तेजी से खोज सकें;)
जीसस

40
@ivanceras: यदि आप इस उत्तर में जानकारी के आधार पर इसे उबाल नहीं सकते हैं, तो कृपया Ask Questionदाईं ओर शीर्ष पर बटन दबाएं ।
बालुसक

3
@Brais: कृपया कल्पना पढ़ें। --भाग सीमा खुद का हिस्सा नहीं है। यह सिर्फ एक विभाजक स्ट्रिंग है। मैंने आपका अमान्य संपादन वापस कर दिया है।
बालूसी

7
@BalusC इस तरह के एक आदर्श ट्यूटोरियल के लिए बहुत बहुत धन्यवाद। कृपया "शीर्ष धारा / कनेक्शन बंद करना" जैसे शीर्षक भी शामिल करें। मैं कब और कौन सी धाराओं / कनेक्शनों को बंद करने के बारे में वास्तव में भ्रमित हूं।

10
दुखद बात यह है कि एंड्रॉइड पर अब अपाचे का उपयोग करने की अनुशंसा नहीं की जाती है HttpClientऔर HttpURLConnectionयह क्रूर है। android-developers.blogspot.in/2011/09/...
यति sagade

91

HTTP के साथ काम HttpURLConnectionकरते समय बेस क्लास के बजाय इसे संदर्भित करने के लिए लगभग हमेशा अधिक उपयोगी होता है URLConnection(क्योंकि URLConnectionजब आप URLConnection.openConnection()HTTP URL पर पूछते हैं तो एक सार वर्ग होता है जो आपको वैसे भी वापस मिल जाएगा)।

तब आप बदले में POST केURLConnection#setDoOutput(true) लिए अनुरोध विधि सेट करने के लिए भरोसा करने के बजाय कर सकते हैं जिसके बजाय कुछ अधिक प्राकृतिक मिल सकता है (और जो आपको अन्य अनुरोध विधियों जैसे PUT , DELETE , ...) को भी निर्दिष्ट करने की अनुमति देता है ।httpURLConnection.setRequestMethod("POST")

यह उपयोगी HTTP स्थिरांक भी प्रदान करता है ताकि आप कर सकें:

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

1
setDoOutPut सच मेरा मुद्दा था जिसने मेरे GET को एक POST में सेट किया। साभार
पैट्रिक काफ्का

22
आप outputstream आप के लिए डेटा लिखने के लिए कोशिश कर रहे हैं चाहिए अभी भी सेट setDoOutput()करने के लिए true(भले ही आप अन्यथा एक अपवाद फेंक दिया जाता है setRequestMethod("POST"))। स्पष्ट है: स्थापित करने URLConnection#setDoOutput(true)के लिए trueपरोक्ष पोस्ट करने के लिए अनुरोध विधि करता है, पर सेटिंग httpURLConnection.setRequestMethod("POST")पोस्ट करने के लिए करता है नहीं परोक्ष सेट setDoOutput()करने के लिए true
टोनी चैन

54

एसओ पर इसके और अन्य सवालों से प्रेरित होकर, मैंने एक न्यूनतम ओपन सोर्स बेसिक-http-क्लाइंट बनाया है जो यहां पाई जाने वाली अधिकांश तकनीकों का प्रतीक है।

google-http-java-client भी एक महान खुला स्रोत संसाधन है।


मैं बस यही सोच रहा था। लेकिन नंगे पैर / सरल जावा पुस्तकालय भी अच्छा हो सकता है जो केवल URLConnection कोड का उपयोग करता है जैसा कि यहां प्रस्तुत किया गया है जो HTTP GET, POST, आदि करने के लिए सरल तरीकों के लिए कोड को एन्क्रिप्ट करता है। पुस्तकालय को तब JAR के रूप में संकलित और पैक किया जा सकता है। जावा कोड में इम्पोर्टेड / यूज्ड या सोर्स क्लास फाइल को जावा प्रोजेक्ट में शामिल किया जा सकता है यदि बाहरी JARs वांछित नहीं हैं। यह अपाचे जैसे अन्य पुस्तकालयों के साथ किया जा सकता है, लेकिन URLConnection का उपयोग करके एक साधारण 1 फ़ाइल क्लास लाइब्रेरी की तुलना में अधिक दर्द होता है।
डेविड


24

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

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

// 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);

24

HTTP यूआरएल हिट्स: GET / POST के साथ आप 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()));

पोस्ट अनुरोध: -

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()));

3
आप वास्तविक JSON प्रतिक्रिया कैसे देख सकते हैं?
सोरा

21

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

मैं अक्सर उन परियोजनाओं पर आता हूं जहां मुझे कुछ HTTP करने की आवश्यकता होती है, और मैं बहुत सारे 3 पार्टी निर्भरताएं नहीं लाना चाहता हूं (जो कि दूसरों को और इतने पर और इतने पर लाते हैं, आदि)

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

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

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


2
यह अजीब है कि doPostविधि में एक charsetपैराम है, जिसका उपयोग अनुरोध हेडर सेट करने के लिए किया जाता है, लेकिन फिर डेटा को कुछ हार्ड-कोडित चारसेट के साथ लिखा जाता है IO.CHARSET। एक दोष?
विट खुडेंको

21

अपडेट करें

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

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

// GET
HttpResponse response = HttpRequest
    .create(new URI("http://www.stackoverflow.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;
}

1
आगे का अद्यतन: मॉड्यूल ऊष्मायन स्थिति से बाहर है। यह अब java.net.http है , jdk.incubator.httpclient नहीं।
वीजीआर

17

प्रारंभ में मुझे इस लेख द्वारा गुमराह किया गया था जो कि एहसान करता है HttpClient

बाद में मुझे एहसास हुआ कि HttpURLConnectionइस लेख से अलग रहना है

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

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

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

इस लेख और प्रवाह के सवालों पर कुछ अन्य स्टैक को पढ़ने के बाद , मुझे यकीन है कि HttpURLConnectionअब और अवधि के लिए रहने वाला है।

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

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

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


15

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

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

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

OkHttpClient client = new OkHttpClient();

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

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

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

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

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


14

आप jcabi-http (मैं एक डेवलपर) JdkRequestसे भी उपयोग कर सकते हैं , जो आपके लिए यह सब काम करता है, HttpURLConnection को सजाने, HTTP अनुरोधों को भरने और जवाब देने के लिए पार्सिंग, उदाहरण के लिए:

String html = new JdkRequest("http://www.google.com").fetch().body();

अधिक जानकारी के लिए इस ब्लॉग पोस्ट की जाँच करें: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html


1
आप कुकीज़ कैसे संभालते हैं?
देजेल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.