Question

En Java, ce code lève une exception lorsque le résultat HTTP correspond à la plage 404:

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

Dans mon cas, je sais que le contenu est 404, mais j'aimerais quand même lire le corps de la réponse.

(Dans mon cas, le code de réponse est 403, mais le corps de la réponse explique la raison du rejet, et j'aimerais l'afficher à l'utilisateur.)

Comment puis-je accéder au corps de la réponse?

Était-ce utile?

La solution

Voici le rapport de bogue (fermer, ne corrigera pas, pas un bug).

Leur conseil est de coder comme ceci:

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

Autres conseils

C'est le même problème que j'avais: HttpUrlConnection renvoie FileNotFoundException si vous essayez de lire le getInputStream () à partir de la connexion.
Vous devriez plutôt utiliser getErrorStream () lorsque le code d'état est supérieur à 400.

Plus que cela, s'il vous plaît soyez prudent, car ce n'est pas seulement le code d'état de réussite 200, même 201, 204, etc. sont souvent utilisés comme états de réussite.

Voici un exemple de la façon dont je suis allé le gérer

... 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....

De cette manière, vous pourrez obtenir la réponse nécessaire dans les cas de réussite et d'erreur.

J'espère que cela aide!

Dans .Net, vous avez la propriété Response de la WebException qui donne accès au flux ON une exception. Donc, je suppose que c’est un bon moyen pour Java, ...

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

Ou une implémentation que j'ai utilisée. (Peut nécessiter des modifications pour le codage ou autre chose. Fonctionne dans l'environnement actuel.)

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

Je sais que cela ne répond pas directement à la question, mais au lieu d'utiliser la bibliothèque de connexions HTTP fournie par Sun, jetez un coup d'œil à Commons HttpClient , qui (à mon avis) a une API beaucoup plus facile à utiliser.

Commencez par vérifier le code de réponse, puis utilisez HttpURLConnection.getErrorStream ()

InputStream is = null;
if (httpConn.getResponseCode() !=200) {
    is = httpConn.getErrorStream();
} else {
     /* error from server */
    is = httpConn.getInputStream();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top