سؤال

في جاوة، هذا الرمز يطرح استثناء عندما تكون النتيجة هي HTTP 404 مجموعة:

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

في حالتي، وأنا أعلم أن المحتوى هو 404، ولكن كنت لا تزال ترغب في قراءة الجسم للاستجابة على أي حال.

و(في حالتي الفعلية رمز الاستجابة 403، ولكن الجسم للاستجابة يوضح سبب الرفض، وأود أن عرض هذا للمستخدم).

وكيف يمكنني الوصول إلى الجسم استجابة؟

هل كانت مفيدة؟

المحلول

هنا هو تقرير علة (وثيقة، لن إصلاح، ليس خطأ).

ومشورتهم هناك لرمز مثل هذا:

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

نصائح أخرى

وانها نفس المشكلة كنت أعاني: عودة HttpUrlConnection FileNotFoundException إذا حاولت قراءة getInputStream() من الاتصال.
يجب أن تستخدم getErrorStream() عندما قانون الأحوال أعلى من 400.

وأكثر من ذلك، يرجى توخي الحذر لأنها ليست 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....

في هذه الطريقة، عليك أن تكون قادرا على الحصول على الاستجابة المطلوبة في كل من النجاح وحالات الخطأ.

ويساعد هذا الأمل!

في صافي لديك خاصية الاستجابة للWebException الذي يعطي الوصول إلى تيار ON استثناء. لذلك أنا أعتقد أن هذا هو وسيلة جيدة للجافا، ...

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

وأنا أعلم أن هذا لا يجيب على السؤال مباشرة، ولكن بدلا من استخدام مكتبة اتصال HTTP التي توفرها الشمس، قد ترغب في إلقاء نظرة على الموقع العموم HttpClient وإصلاحه ، والتي (في رأيي) لديه API أسهل بكثير من التعامل معها.

أولا التحقق من رمز الاستجابة ومن ثم استخدام HttpURLConnection.getErrorStream()

InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top