जावा में त्रुटि प्रतिक्रिया निकाय पढ़ें


93

जावा में, यह कोड एक अपवाद फेंकता है जब HTTP परिणाम 404 रेंज है:

URL url = new URL("http://stackoverflow.com/asdf404notfound");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // throws!

मेरे मामले में, मुझे पता है कि सामग्री 404 है, लेकिन मैं अभी भी प्रतिक्रिया के शरीर को वैसे भी पढ़ना चाहूंगा।

(मेरे वास्तविक मामले में प्रतिक्रिया कोड 403 है, लेकिन प्रतिक्रिया का शरीर अस्वीकृति का कारण बताता है, और मैं इसे उपयोगकर्ता को प्रदर्शित करना चाहूंगा।)

मैं प्रतिक्रिया निकाय को कैसे एक्सेस कर सकता हूं?


क्या आप सुनिश्चित हैं कि सर्वर एक निकाय भेज रहा है?
हांक गे

2
@jdigital: HttpURLConnection.getInputStream () द्वारा फेंका गया अपवाद java.io.FileNotFoundException है। (मुख्य रूप से बेहतर googlability के लिए इस उल्लेख के।)
Jonik

जवाबों:


172

यहाँ बग रिपोर्ट है (करीब, ठीक नहीं होगा, बग नहीं)।

उनकी सलाह इस तरह कोड है:

HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
    _is = httpConn.getInputStream();
} else {
     /* error from server */
    _is = httpConn.getErrorStream();
}

5
क्या आप त्रुटि धारा तब प्राप्त करना चाहेंगे, जब प्रतिक्रिया कोड> = 400 हो, बजाय अन्य तरीके के?
स्टीफन स्वेंसन

3
त्रुटियों के मामले में, getInputStream () एक IO अपवाद को फेंक देगा। आपको अपवाद को पकड़ना चाहिए और getErrorStream () का उपयोग करके त्रुटि स्ट्रीम से पढ़ना चाहिए। यह रिप्रेजेंट कोड पर चेक करने से बेहतर तरीका लगता है।
सुदर्शन भट

3
समस्या यह है कि यदि आप HttpUrlConnection.getErrorStream () कोड पढ़ते हैं, तो आप देखेंगे कि यह हमेशा शून्य है। (जावा ६) :-(
गंगानुस २५'१४

6
अन्य सफल कोड जैसे "201 क्रिएट" यहां असफल नहीं होंगे?
रिच

4
बग रिपोर्ट में सुझाव दिया गया है कि httpConn.getResponseCode() >= 400(और उनके काम के आसपास की त्रुटि है, इनपुटस्ट्रीम का उपयोग करने के लिए फ़्लिप करें)
Dag

14

यह वही समस्या है जो मुझे हो रही थी: यदि आप कनेक्शन से पढ़ने की कोशिश करते हैं तो HttpUrlConnectionरिटर्न । जब स्थिति कोड 400 से अधिक हो, तो आपको इसके बजाय उपयोग करना चाहिए ।FileNotFoundExceptiongetInputStream()
getErrorStream()

इससे अधिक, कृपया सावधान रहें क्योंकि यह सफलता की स्थिति कोड होने के लिए केवल 200 ही नहीं है, यहां तक ​​कि 201, 204, आदि का उपयोग अक्सर सावधानियों के रूप में किया जाता है।

यहाँ एक उदाहरण है कि मैं इसे कैसे प्रबंधित करने गया

... connection code code code ...

// Get the response code 
int statusCode = connection.getResponseCode();

InputStream is = null;

if (statusCode >= 200 && statusCode < 400) {
   // Create an InputStream in order to extract the response object
   is = connection.getInputStream();
}
else {
   is = connection.getErrorStream();
}

... callback/response to your handler....

इस तरह, आप सफलता और त्रुटि दोनों मामलों में आवश्यक प्रतिक्रिया प्राप्त कर सकेंगे।

उम्मीद है की यह मदद करेगा!


13

.Net में आपके पास WebException की रिस्पॉन्स प्रॉपर्टी है जो किसी अपवाद पर स्ट्रीम तक पहुंच प्रदान करता है। तो मुझे लगता है कि यह जावा के लिए एक अच्छा तरीका है, ...

private InputStream dispatch(HttpURLConnection http) throws Exception {
    try {
        return http.getInputStream();
    } catch(Exception ex) {
        return http.getErrorStream();
    }
}

या एक कार्यान्वयन मैं इस्तेमाल किया। (एन्कोडिंग या अन्य चीजों के लिए परिवर्तनों की आवश्यकता हो सकती है। वर्तमान परिवेश में काम करता है।)

private String dispatch(HttpURLConnection http) throws Exception {
    try {
        return readStream(http.getInputStream());
    } catch(Exception ex) {
        readAndThrowError(http);
        return null; // <- never gets here, previous statement throws an error
    }
}

private void readAndThrowError(HttpURLConnection http) throws Exception {
    if (http.getContentLengthLong() > 0 && http.getContentType().contains("application/json")) {
        String json = this.readStream(http.getErrorStream());
        Object oson = this.mapper.readValue(json, Object.class);
        json = this.mapper.writer().withDefaultPrettyPrinter().writeValueAsString(oson);
        throw new IllegalStateException(http.getResponseCode() + " " + http.getResponseMessage() + "\n" + json);
    } else {
        throw new IllegalStateException(http.getResponseCode() + " " + http.getResponseMessage());
    }
}

private String readStream(InputStream stream) throws Exception {
    StringBuilder builder = new StringBuilder();
    try (BufferedReader in = new BufferedReader(new InputStreamReader(stream))) {
        String line;
        while ((line = in.readLine()) != null) {
            builder.append(line); // + "\r\n"(no need, json has no line breaks!)
        }
        in.close();
    }
    System.out.println("JSON: " + builder.toString());
    return builder.toString();
}

यह स्वीकृत उत्तर होना चाहिए ... मुझे आश्चर्य है कि लोग अभी भी अपवादों को संभालने के बजाय जादू की संख्याओं का सत्यापन क्यों करते हैं ...
स्पार्क

मुझे आश्चर्य है कि यह स्वीकृत उत्तर पर क्यों नहीं है। मेरी बहुत मदद की। धन्यवाद!
निखिल जैन

2

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


4
क्षमा करें मैं असहमत हूं। सूर्य से एपीआई बहुत आसान है, जब तक आप वास्तव में सरल सामान करते हैं। साधारण सामान से मेरा मतलब है कि बहुत अधिक त्रुटि से निपटने के बिना बस एक जीईटी, जो बड़ी संख्या में मामलों के लिए पर्याप्त है। बेशक HttpClient कार्यक्षमता में कहीं बेहतर है।
माइकल पीफेल

2014 तक, ओकेहटप सबसे अच्छा हो सकता है (जो वास्तव में URL खोलते समय HttpURLConnection उदाहरण देता है)। विशेष रूप से एंड्रॉइड पर यह आपको सादे HttpURLConnection और Apache HttpClient दोनों की कुछ खराब समस्याओं से बचने में मदद कर सकता है।
जोनीक


1
InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}

4
अन्य सफल कोड जैसे "201 क्रिएट" यहां असफल नहीं होंगे?
रिच

हां @ रीच, इसीलिए ऐसा करना बेहतर होगा:if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
AO_

1

मेरा रनिंग कोड।

  HttpURLConnection httpConn = (HttpURLConnection) urlConn;    
 if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
                        in = new InputStreamReader(urlConn.getInputStream());
                        BufferedReader bufferedReader = new BufferedReader(in);
                        if (bufferedReader != null) {
                            int cp;
                            while ((cp = bufferedReader.read()) != -1) {
                                sb.append((char) cp);
                            }
                            bufferedReader.close();
                        }
                            in.close();

                    } else {
                        /* error from server */
                        in = new InputStreamReader(httpConn.getErrorStream());
                    BufferedReader bufferedReader = new BufferedReader(in);
                    if (bufferedReader != null) {
                        int cp;
                        while ((cp = bufferedReader.read()) != -1) {
                            sb.append((char) cp);
                        }
                        bufferedReader.close();
                    }    
                    in.close();
                    }
                    System.out.println("sb="+sb);

0

जावा में 404 रेस्पॉन्स बॉडी कैसे पढ़ें:

अपाचे लाइब्रेरी का उपयोग करें - https://hc.apache.org/httpcompenders-client-4.5.x/httpclient/apidocs/

या जावा 11 - https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html

नीचे दिया गया स्निपेट अपाचे का उपयोग करता है:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse resp = client.execute(new HttpGet(domainName + "/blablablabla.html"));
String response = EntityUtils.toString(resp.getEntity());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.